Attach the browser console to a failing e2e test (#525)
This commit is contained in:
parent
8c81550695
commit
3acc447a87
2 changed files with 31 additions and 0 deletions
|
|
@ -414,6 +414,11 @@ pnpm test # starts and stops the con
|
||||||
|
|
||||||
Every test skips when docker is unavailable, rather than failing.
|
Every test skips when docker is unavailable, rather than failing.
|
||||||
|
|
||||||
|
A failing test attaches `browser-console`, the console errors and uncaught exceptions its pages
|
||||||
|
raised. `use.trace` and playwright's own reporting only cover contexts playwright made itself, and
|
||||||
|
the harness makes its own, so without that attachment a failure carries the DOM snapshot and
|
||||||
|
nothing the app said — which is unreadable when what failed is the app rendering its error page.
|
||||||
|
|
||||||
One engine per run. These specs exercise sockets, auth and sync, so running them under three
|
One engine per run. These specs exercise sockets, auth and sync, so running them under three
|
||||||
engines adds little coverage. `E2E_BROWSER=webkit pnpm test` runs the whole
|
engines adds little coverage. `E2E_BROWSER=webkit pnpm test` runs the whole
|
||||||
suite under another one. The container listens on a fixed port and cannot be sharded, so
|
suite under another one. The container listens on a fixed port and cannot be sharded, so
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {writeFile} from "node:fs/promises"
|
||||||
import {npubEncode} from "nostr-tools/nip19"
|
import {npubEncode} from "nostr-tools/nip19"
|
||||||
import {test as base, expect} from "@playwright/test"
|
import {test as base, expect} from "@playwright/test"
|
||||||
import type {BrowserContext, BrowserContextOptions, Page} from "@playwright/test"
|
import type {BrowserContext, BrowserContextOptions, Page} from "@playwright/test"
|
||||||
|
|
@ -193,6 +194,7 @@ export const test = base.extend<HarnessFixtures, HarnessWorkerFixtures>({
|
||||||
await zooid.reset()
|
await zooid.reset()
|
||||||
|
|
||||||
const contexts: BrowserContext[] = []
|
const contexts: BrowserContext[] = []
|
||||||
|
const browserLog: string[] = []
|
||||||
|
|
||||||
let scenario: Maybe<Scenario>
|
let scenario: Maybe<Scenario>
|
||||||
|
|
||||||
|
|
@ -218,6 +220,21 @@ export const test = base.extend<HarnessFixtures, HarnessWorkerFixtures>({
|
||||||
|
|
||||||
contexts.push(context)
|
contexts.push(context)
|
||||||
|
|
||||||
|
// `use.trace` and the built-in reporting only cover contexts playwright made itself, so a
|
||||||
|
// failure in a context opened here arrives with the app's own account of it thrown away —
|
||||||
|
// which is how a spec that caught the app on its 500 page had nothing to say about why.
|
||||||
|
const who = user?.name ?? "anonymous"
|
||||||
|
|
||||||
|
context.on("console", message => {
|
||||||
|
if (["error", "warning"].includes(message.type())) {
|
||||||
|
browserLog.push(`[${who}] ${message.type()}: ${message.text()}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
context.on("weberror", error => {
|
||||||
|
browserLog.push(`[${who}] uncaught: ${error.error().stack ?? error.error().message}`)
|
||||||
|
})
|
||||||
|
|
||||||
// Playwright matches the most recently registered route first and every mock falls through
|
// Playwright matches the most recently registered route first and every mock falls through
|
||||||
// what it doesn't recognize, so the block-all goes in before the mocks, and all of it before
|
// what it doesn't recognize, so the block-all goes in before the mocks, and all of it before
|
||||||
// the page navigates.
|
// the page navigates.
|
||||||
|
|
@ -277,6 +294,15 @@ export const test = base.extend<HarnessFixtures, HarnessWorkerFixtures>({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (browserLog.length > 0 && testInfo.status !== testInfo.expectedStatus) {
|
||||||
|
// A path rather than a body: the list reporter truncates an inline attachment, and the
|
||||||
|
// nightly run on the box keeps test-results and nothing else.
|
||||||
|
const path = testInfo.outputPath("browser-console.log")
|
||||||
|
|
||||||
|
await writeFile(path, browserLog.join("\n"))
|
||||||
|
await testInfo.attach("browser-console", {path, contentType: "text/plain"})
|
||||||
|
}
|
||||||
|
|
||||||
for (const context of contexts) {
|
for (const context of contexts) {
|
||||||
await context.close()
|
await context.close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue