Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,11 @@ jobs:
run: pnpm run test:e2e:install
- name: Run E2E Tests
run: pnpm run test:e2e
- name: Upload E2E failure artifacts
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: e2e-failures
path: test-results/
if-no-files-found: ignore
retention-days: 7
57 changes: 25 additions & 32 deletions examples/alpine/realtime-trading/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,49 +82,42 @@ test('runs the Alpine realtime trading workload', async ({ page }) => {
const publishInterval = page.getByTestId('publish-interval-select')
await expect(publishInterval.locator('option[value="500"]')).toHaveCount(1)
await expect(publishInterval.locator('option[value="1000"]')).toHaveCount(1)
await publishInterval.selectOption('100')

await resumeTradingFeed(page)

await expect
.poll(async () => {
const text = await page.getByTestId('row-update-rate').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('message-rate').textContent()),
)
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('table-render-rate').textContent()),
)
.toBeGreaterThan(0)
// Exercise delivery and rendering without turning this smoke test into a
// throughput benchmark on shared CI runners. Configure controls while paused.
await setRangeValue(targetRateSlider, '0')
await expect(page.getByTestId('target-sample-rate')).toContainText(
'100 samples/s',
)
await publishInterval.selectOption('500')
await expect(publishInterval).toHaveValue('500')
await sparklineInterval.selectOption('100')
const swapRenderer = page.getByRole('checkbox', {
name: /Swap Tick component/,
})
await swapRenderer.check()
await expect(swapRenderer).toBeChecked()

const firstPrice = page.locator('tbody tr').first().getByRole('button')
const firstPrice = table.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await resumeTradingFeed(page)
await expect
.poll(() => firstPrice.textContent())
.not.toBe(priceBeforeUpdate)

await page.locator('.config-section input[type="checkbox"]').first().check()
await page.getByTestId('feed-toggle').click()
await expect(page.getByTestId('feed-toggle')).toHaveText('START FEED')
await expect(page.getByTestId('feed-status')).toHaveText('FEED PAUSED')

expect(
await page.evaluate(
() => performance.getEntriesByName('tanstack-row-model').length > 0,
),
).toBe(true)
// Delivery is cumulative; instantaneous rates can legitimately fall to
// zero between samples on a busy runner. The price assertion above proves
// that a delivered update reached the rendered table.
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)

expect(errors).toEqual([])
} finally {
Expand Down
56 changes: 26 additions & 30 deletions examples/lit/realtime-trading/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,46 +137,42 @@ test('runs the Lit realtime trading workload', async ({ page }) => {
await expect(publishInterval.locator('option[value="500"]')).toHaveCount(1)
await expect(publishInterval.locator('option[value="1000"]')).toHaveCount(1)

await resumeTradingFeed(page)
await expect
.poll(async () => {
const text = await page.getByTestId('row-update-rate').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('message-rate').textContent()),
)
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('table-render-rate').textContent()),
)
.toBeGreaterThan(0)
// Exercise delivery and rendering without turning this smoke test into a
// throughput benchmark on shared CI runners. Configure controls while paused.
await setRangeValue(targetRateSlider, '0')
await expect(page.getByTestId('target-sample-rate')).toContainText(
'100 samples/s',
)
await publishInterval.selectOption('500')
await expect(publishInterval).toHaveValue('500')
await sparklineInterval.selectOption('100')
const swapRenderer = page.getByRole('checkbox', {
name: /Swap Tick component/,
})
await swapRenderer.check()
await expect(swapRenderer).toBeChecked()

const firstPrice = page.locator('tbody tr').first().getByRole('button')
const firstPrice = table.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await resumeTradingFeed(page)
await expect
.poll(() => firstPrice.textContent())
.not.toBe(priceBeforeUpdate)

await page.locator('.config-section input[type="checkbox"]').first().check()
await pauseTradingFeed(page)

await instrumentCount.selectOption('750')
await expect.poll(() => table.locator('tbody tr').count()).toBeLessThan(750)
expect(
await page.evaluate(
() => performance.getEntriesByName('tanstack-row-model').length > 0,
),
).toBe(true)

// Delivery is cumulative; instantaneous rates can legitimately fall to
// zero between samples on a busy runner. The price assertion above proves
// that a delivered update reached the rendered table.
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)

expect(errors).toEqual([])
} finally {
Expand Down
35 changes: 26 additions & 9 deletions examples/octane/realtime-trading/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,23 @@ test('runs the Octane realtime trading workload', async ({ page }) => {
await expect(publishInterval.locator('option[value="500"]')).toHaveCount(1)
await expect(publishInterval.locator('option[value="1000"]')).toHaveCount(1)

// Exercise delivery and rendering without turning this smoke test into a
// throughput benchmark on shared CI runners. Configure controls while paused.
await setRangeValue(targetRateSlider, '3')
await expect(page.getByTestId('target-sample-rate')).toContainText(
'1K samples/s',
)
await publishInterval.selectOption('250')
await expect(publishInterval).toHaveValue('250')
await sparklineInterval.selectOption('100')
const swapRenderer = page.getByRole('checkbox', {
name: /Swap Tick component/,
})
await swapRenderer.check()
await expect(swapRenderer).toBeChecked()

const firstPrice = table.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await resumeTradingFeed(page)
await expect
.poll(async () => {
Expand All @@ -107,21 +124,21 @@ test('runs the Octane realtime trading workload', async ({ page }) => {
)
.toBeGreaterThan(0)

const firstPrice = page.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await expect
.poll(() => firstPrice.textContent())
.not.toBe(priceBeforeUpdate)

await page.locator('.config-section input[type="checkbox"]').first().check()
// Row-model timing is sampled every twentieth call, so wait for a sample
// before stopping the lower-rate feed.
await expect
.poll(() =>
page.evaluate(
() => performance.getEntriesByName('tanstack-row-model').length,
),
)
.toBeGreaterThan(0)
await pauseTradingFeed(page)

expect(
await page.evaluate(
() => performance.getEntriesByName('tanstack-row-model').length > 0,
),
).toBe(true)

expect(errors).toEqual([])
} finally {
await server.close()
Expand Down
52 changes: 26 additions & 26 deletions examples/solid/realtime-trading/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ test('runs the Solid realtime trading workload', async ({ page }) => {
4,
)
await expect(table.locator('td[data-selection-left="true"]')).toHaveCount(3)
await resumeTradingFeed(page)

await expect(page.getByTestId('feed-status')).toHaveText('FEED LIVE')
await expect(instrumentCount.locator('option[value="150"]')).toHaveCount(1)
await expect(instrumentCount.locator('option[value="350"]')).toHaveCount(1)
await expect(instrumentCount.locator('option[value="750"]')).toHaveCount(1)
Expand Down Expand Up @@ -172,38 +170,40 @@ test('runs the Solid realtime trading workload', async ({ page }) => {
await expect(publishInterval.locator('option[value="500"]')).toHaveCount(1)
await expect(publishInterval.locator('option[value="1000"]')).toHaveCount(1)

await expect
.poll(async () => {
const text = await page.getByTestId('row-update-rate').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('message-rate').textContent()),
)
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('table-render-rate').textContent()),
)
.toBeGreaterThan(0)
// Exercise delivery and rendering without turning this smoke test into a
// throughput benchmark on shared CI runners. Configure controls while paused.
await setRangeValue(targetRateSlider, '0')
await expect(page.getByTestId('target-sample-rate')).toContainText(
'100 samples/s',
)
await publishInterval.selectOption('500')
await expect(publishInterval).toHaveValue('500')
await sparklineInterval.selectOption('100')
const swapRenderer = page.getByRole('checkbox', {
name: /Swap Tick component/,
})
await swapRenderer.check()
await expect(swapRenderer).toBeChecked()

const firstPrice = page.locator('tbody tr').first().getByRole('button')
const firstPrice = table.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await resumeTradingFeed(page)
await expect
.poll(() => firstPrice.textContent())
.not.toBe(priceBeforeUpdate)

await page.locator('.config-section input[type="checkbox"]').first().check()
await pauseTradingFeed(page)

// Delivery is cumulative; instantaneous rates can legitimately fall to
// zero between samples on a busy runner. The price assertion above proves
// that a delivered update reached the rendered table.
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)

expect(errors).toEqual([])
} finally {
await server.close()
Expand Down
58 changes: 26 additions & 32 deletions examples/svelte/realtime-trading/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,51 +136,45 @@ test('runs the Svelte realtime trading workload', async ({ page }) => {
const publishInterval = page.getByTestId('publish-interval-select')
await expect(publishInterval.locator('option[value="500"]')).toHaveCount(1)
await expect(publishInterval.locator('option[value="1000"]')).toHaveCount(1)
await publishInterval.selectOption('100')

await resumeTradingFeed(page)

await expect
.poll(async () => {
const text = await page.getByTestId('row-update-rate').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('message-rate').textContent()),
)
.toBeGreaterThan(0)
await expect
.poll(async () =>
Number(await page.getByTestId('table-render-rate').textContent()),
)
.toBeGreaterThan(0)
// Exercise delivery and rendering without turning this smoke test into a
// throughput benchmark on shared CI runners. Configure controls while paused.
await setRangeValue(targetRateSlider, '0')
await expect(page.getByTestId('target-sample-rate')).toContainText(
'100 samples/s',
)
await publishInterval.selectOption('500')
await expect(publishInterval).toHaveValue('500')
await sparklineInterval.selectOption('100')
const swapRenderer = page.getByRole('checkbox', {
name: /Swap Tick component/,
})
await swapRenderer.check()
await expect(swapRenderer).toBeChecked()

const firstPrice = page.locator('tbody tr').first().getByRole('button')
const firstPrice = table.locator('tbody tr').first().getByRole('button')
const priceBeforeUpdate = await firstPrice.textContent()
await resumeTradingFeed(page)
await expect
.poll(() => firstPrice.textContent())
.not.toBe(priceBeforeUpdate)

await page.locator('.config-section input[type="checkbox"]').first().check()
await page.getByTestId('feed-toggle').click()
await expect(page.getByTestId('feed-toggle')).toHaveText('START FEED')
await expect(page.getByTestId('feed-status')).toHaveText('FEED PAUSED')

// Delivery is cumulative; instantaneous rates can legitimately fall to
// zero between samples on a busy runner. The price assertion above proves
// that a delivered update reached the rendered table.
await expect
.poll(async () => {
const text = await page.getByTestId('worker-messages').textContent()
return Number(text?.replace(/\D/g, '') ?? 0)
})
.toBeGreaterThan(0)

await instrumentCount.selectOption('750')
await expect.poll(() => table.locator('tbody tr').count()).toBeLessThan(750)
expect(
await page.evaluate(
() => performance.getEntriesByName('tanstack-row-model').length > 0,
),
).toBe(true)

expect(errors).toEqual([])
} finally {
Expand Down
Loading
Loading