Repository navigation
test(fixtures): inject Playwright objects through JUnit 5 fixtures - #2017
Conversation
Replace the TestBase base class and @UsePlaywright with a fixture layer in com.microsoft.playwright.fixtures modeled on upstream browserTest.ts: - @PlaywrightTest runs each test once per browser (BROWSER env selects) - Playwright, Browser, BrowserContext, Page, Server etc. are injected as method parameters and created lazily, each test in a new context - @fixture methods add or override fixtures (test or worker scope) - worker-scoped objects live in a pool so tests run in parallel without sharing Playwright objects across threads - @DisabledOnBrowser/@EnabledOnBrowser replace @DisabledIf conditions - @nested @ParameterizedClass runs a test with different context options Claude-Session: https://claude.ai/code/session_018p7xPf3r5VjAM7V46nzFTM
| // Like Playwright Test, do not reuse a worker after a failure: the test may have left the | ||
| // browser or the Playwright instance in an unknown state. | ||
| boolean failed = context.getExecutionException().filter(e -> !(e instanceof TestAbortedException)).isPresent(); | ||
| WorkerPool.INSTANCE.release(worker, failed); |
There was a problem hiding this comment.
contexts created directly by tests survive worker reuse which breaks context count assertions in later test classes
There was a problem hiding this comment.
Fixed in ed346c3. The worker records the contexts its own fixtures create. Before the pool hands a worker to the next test, it closes any other context still open in the worker's browsers. TestWorkerFixtures covers this: the first test leaves a context open and the second asserts that browser.contexts() holds only the worker fixture's context.
| try { | ||
| entry.definition.close(entry.value); | ||
| } catch (Throwable e) { | ||
| System.err.println("Failed to close " + entry.definition.describe() + ": " + e); |
There was a problem hiding this comment.
swallowing cleanup errors lets tests pass when context or fixture teardown fails
There was a problem hiding this comment.
Fixed in ed346c3. Teardown still closes everything, then rethrows the first error with the others attached as suppressed. The test fails (JUnit reports "Failed to close extension context") and its worker is discarded. Errors from closing workers that no test owns, evicted or idle at the end of the run, fail the whole run and name the worker.
|
|
||
| @PlaywrightTest | ||
| void shouldReuseWorkerFixtures(Browser browser, WorkerResource resource) { | ||
| assertSame(browser, resource.browser); |
There was a problem hiding this comment.
this passes even with a new worker for every test so it does not actually check fixture reuse
There was a problem hiding this comment.
Agreed, fixed in ed346c3. TestWorkerFixtures now runs @Isolated and in a fixed order, and asserts that both tests in each browser got the same worker fixture instance and that it was not closed in between. The new TestWorkerPool covers reuse, eviction and discarding deterministically without browsers. Writing this exposed a real problem: the pool kept one worker per test thread while each thread runs every test in all three browsers, so a sequential run relaunched the browser for every invocation. The pool now holds threads × browsers workers.
- close contexts a test leaves open in a worker's browsers before the worker is reused, keeping the ones created by worker fixtures - fail the test when closing its fixtures fails and discard the worker; failures to close idle or evicted workers fail the run - keep a worker per browser for every test thread, since each thread runs a test in all browsers in turn, and close idle workers in parallel at the end of the run - check worker reuse with pool unit tests and an isolated integration test Claude-Session: https://claude.ai/code/session_018p7xPf3r5VjAM7V46nzFTM
Summary
TestBaseand@UsePlaywrightin the test suite with a fixture layer incom.microsoft.playwright.fixtures, modeled on upstreambrowserTest.ts@PlaywrightTestruns each test once per browser;Playwright,Browser,BrowserContext,Page,Serverare injected as parameters, each test in a new context@Fixturemethods override test- or worker-scoped fixtures; worker objects are pooled so tests run in parallel without sharing Playwright objects across threads@DisabledOnBrowser/@EnabledOnBrowserreplace@DisabledIfconditions;@Nested @ParameterizedClassruns a test with different context optionshttps://claude.ai/code/session_018p7xPf3r5VjAM7V46nzFTM