MapleLeaf 🍁
MapleLeaf 🍁
CCConvex Community
Created by MapleLeaf 🍁 on 12/4/2023 in #support-community
e2e testing with preview deployments
I'm trying to get a setup where I can run e2e tests in Github CI against a preview environment. Here's what I have:
- name: Build with Convex deploy
run: pnpm convex deploy
--cmd "pnpm run build"
--cmd-url-env-var-name VITE_PUBLIC_CONVEX_URL
--preview-name "e2e-${{ github.ref_name }}"
env:
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }}

- name: Run Playwright tests
run: pnpm run e2e
env:
CLERK_PUBLISHABLE_KEY: ${{ secrets.CLERK_PUBLISHABLE_KEY }}
CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
- name: Build with Convex deploy
run: pnpm convex deploy
--cmd "pnpm run build"
--cmd-url-env-var-name VITE_PUBLIC_CONVEX_URL
--preview-name "e2e-${{ github.ref_name }}"
env:
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }}

- name: Run Playwright tests
run: pnpm run e2e
env:
CLERK_PUBLISHABLE_KEY: ${{ secrets.CLERK_PUBLISHABLE_KEY }}
CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
I want my tests to run seed functions before they go, e.g.
test.beforeAll(async ({ page }) => {
await execa("pnpm", ["convex", "run", "seed:characters"], {
stdio: "inherit",
})
})

test("navigating characters", async ({ page }) => {
// etc
})
test.beforeAll(async ({ page }) => {
await execa("pnpm", ["convex", "run", "seed:characters"], {
stdio: "inherit",
})
})

test("navigating characters", async ({ page }) => {
// etc
})
this doesn't work in CI because the tests are ran outside the convex deploy context and don't have the CONVEX_DEPLOYMENT environment variable I can --preview-run seed:characters, but I want to be able to run specific functions for specific tests to replicate certain setup scenarios without the test going through the UI to do so so my question is: how can I pass the info from convex deploy such that I can run functions during the tests?
28 replies
CCConvex Community
Created by MapleLeaf 🍁 on 8/23/2023 in #support-community
Feature request: v.nullish(someValidator)
Equivalent to this:
export const nullish = <T>(validator: Validator<T>) =>
v.optional(v.union(validator, v.null()))
export const nullish = <T>(validator: Validator<T>) =>
v.optional(v.union(validator, v.null()))
Because I often CBA whether an input is null or undefined :lul: so many data sources will just decide whether to do one or the other
2 replies
CCConvex Community
Created by MapleLeaf 🍁 on 8/21/2023 in #support-community
Collection size limit
I have a collection of items that'll get created frequently, and I don't need to store them forever, so I want to delete old entries to preserve space. My current strategy is to delete extra items once the collection size is over some arbitrary max. I'm not that worried about performance since the collection isn't that big, nor is the limit, but I still wonder if there's a more performant/idiomatic way to accomplish this. Here's my code:
const maxRolls = 250

export const roll = mutation({
args: {
type: v.optional(v.string()),
label: v.optional(v.string()),
characterId: v.optional(v.id("characters")),
dice: v.array(v.object({ sides: v.number(), count: v.number() })),
},
handler: async (ctx, { dice, ...data }) => {
const user = await requirePlayerUser(ctx)

// make dice rolls
const rolls = []
for (const dieItem of dice) {
for (let i = 0; i < dieItem.count; i++) {
rolls.push({
sides: dieItem.sides,
result: Math.floor(Math.random() * dieItem.sides) + 1,
})
}
}

// add new dice roll
await ctx.db.insert("diceRolls", {
...data,
discordUserId: user.discordUserId,
dice: rolls,
})

// remove old dice rolls if there are too many
const allRolls = await ctx.db.query("diceRolls").collect()
const excessRolls = allRolls.slice(0, -maxRolls)
await Promise.all(excessRolls.map((r) => ctx.db.delete(r._id)))
},
})
const maxRolls = 250

export const roll = mutation({
args: {
type: v.optional(v.string()),
label: v.optional(v.string()),
characterId: v.optional(v.id("characters")),
dice: v.array(v.object({ sides: v.number(), count: v.number() })),
},
handler: async (ctx, { dice, ...data }) => {
const user = await requirePlayerUser(ctx)

// make dice rolls
const rolls = []
for (const dieItem of dice) {
for (let i = 0; i < dieItem.count; i++) {
rolls.push({
sides: dieItem.sides,
result: Math.floor(Math.random() * dieItem.sides) + 1,
})
}
}

// add new dice roll
await ctx.db.insert("diceRolls", {
...data,
discordUserId: user.discordUserId,
dice: rolls,
})

// remove old dice rolls if there are too many
const allRolls = await ctx.db.query("diceRolls").collect()
const excessRolls = allRolls.slice(0, -maxRolls)
await Promise.all(excessRolls.map((r) => ctx.db.delete(r._id)))
},
})
4 replies
CCConvex Community
Created by MapleLeaf 🍁 on 8/18/2023 in #support-community
Feature request: v.record() and v.unknown()
I have a case where I want to store arbitrary data specifically as an object of type Record<string, string | number> but that doesn't seem to be possible with the current validators As a somewhat related aside, v.unknown() would be a much more welcome and safer alternative to v.any()
9 replies