<p dir="auto">Hi there! I am writing a suite of Playwright tests. So far it has mostly been a joy to use.</p>
<p dir="auto">However, I have run into some issues when parallelizing tests. I am pretty sure that this functionality does not exist, but if it does, happy to learn more about it.</p>
<p dir="auto">The vast majority of my tests are independent and can be run in parallel without any issues. Test objects are created at the start of the test and cleaned up at the end. No problem. However, I have a few tests that necessarily affect global state in the application. These can still clean themselves up at the end so the state at the end of the test is the same as the start. However, they can't be run in parallel with any other test because their effects while running will mess with other tests.</p>
<p dir="auto">So far I have solved this by only using one worker and running no tests in parallel. This is not ideal, as it slows tests down a bit. <strong>Is there (or can there be) some way to run all tests with the specified number of workers but run x tests (demarcated somehow in the test) only by themselves?</strong></p>
<p dir="auto">I looked into <a href="https://playwright.dev/docs/api/class-test#test-describe-serial" rel="nofollow">https://playwright.dev/docs/api/class-test#test-describe-serial</a> and thought I had found a way to do this, but this appears to only run tests in a given <code class="notranslate">describe</code> block in serial and not be what I'm actually looking for.</p>
<p dir="auto">My next attempt is probably going to be to try to use some sort of semaphore to get certain tests only to run on their own, but this will be kinda hacky and it would be nice if the framework natively supported this feature.</p>
<p dir="auto">Thank you!</p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: 8.19.1</li>
<li>Operating System: All</li>
<li>Browser: All</li>
<li>Other info:</li>
</ul>
<h3 dir="auto">Source code</h3>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="test.describe('Test', () =&gt; {
  // should be WorkerInfo but is typed as TestInfo
  test.beforeAll(async ({ browser }, workerInfo) =&gt; {});
  // correctly typed as TestInfo
  test.afterEach(async ({}, testInfo) =&gt; {});"><pre class="notranslate"><span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-c1">describe</span><span class="pl-kos">(</span><span class="pl-s">'Test'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c">// should be WorkerInfo but is typed as TestInfo</span>
  <span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">beforeAll</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> browser <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">workerInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c">// correctly typed as TestInfo</span>
  <span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">afterEach</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Steps</strong><br>
No special config or steps are needed - you can also simply check the <code class="notranslate">test.d.ts</code> type definitions file to confirm this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  /**
   * Declares a `beforeAll` hook that is executed once per worker process before all tests.
   *
   * **Details**
   *
   * When called in the scope of a test file, runs before all tests in the file. When called inside a
   * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group, runs before all
   * tests in the group. If multiple `beforeAll` hooks are added, they will run in the order of their registration.
   *
   * Note that worker process is restarted on test failures, and `beforeAll` hook runs again in the new worker. Learn
   * more about [workers and failures](https://playwright.dev/docs/test-retries).
   *
   * You can use [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all) to teardown
   * any resources set up in `beforeAll`.
   *
   * **Usage**
   *
   * ```js
   * // example.spec.ts
   * import { test, expect } from '@playwright/test';
   *
   * test.beforeAll(async () =&gt; {
   *   console.log('Before tests');
   * });
   *
   * test.afterAll(async () =&gt; {
   *   console.log('After tests');
   * });
   *
   * test('my test', async ({ page }) =&gt; {
   *   // ...
   * });
   * ```
   *
   * @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
   */
  beforeAll(inner: (args: TestArgs &amp; WorkerArgs, testInfo: TestInfo) =&gt; Promise&lt;any&gt; | any): void;
  /**
   * Declares an `afterAll` hook that is executed once per worker after all tests.
   *
   * **Details**
   *
   * When called in the scope of a test file, runs after all tests in the file. When called inside a
   * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group, runs after all
   * tests in the group. If multiple `afterAll` hooks are added, they will run in the order of their registration.
   *
   * Note that worker process is restarted on test failures, and `afterAll` hook runs again in the new worker. Learn
   * more about [workers and failures](https://playwright.dev/docs/test-retries).
   *
   * **Usage**
   *
   * ```js
   * test.afterAll(async () =&gt; {
   *   console.log('Done with tests');
   *   // ...
   * });
   * ```
   *
   * @param hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].
   */
  afterAll(inner: (args: TestArgs &amp; WorkerArgs, testInfo: TestInfo) =&gt; Promise&lt;any&gt; | any): void;"><pre class="notranslate">  <span class="pl-c">/**</span>
<span class="pl-c">   * Declares a `beforeAll` hook that is executed once per worker process before all tests.</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * **Details**</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * When called in the scope of a test file, runs before all tests in the file. When called inside a</span>
<span class="pl-c">   * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group, runs before all</span>
<span class="pl-c">   * tests in the group. If multiple `beforeAll` hooks are added, they will run in the order of their registration.</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * Note that worker process is restarted on test failures, and `beforeAll` hook runs again in the new worker. Learn</span>
<span class="pl-c">   * more about [workers and failures](https://playwright.dev/docs/test-retries).</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * You can use [test.afterAll(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-all) to teardown</span>
<span class="pl-c">   * any resources set up in `beforeAll`.</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * **Usage**</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * ```js</span>
<span class="pl-c">   * // example.spec.ts</span>
<span class="pl-c">   * import { test, expect } from '@playwright/test';</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * test.beforeAll(async () =&gt; {</span>
<span class="pl-c">   *   console.log('Before tests');</span>
<span class="pl-c">   * });</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * test.afterAll(async () =&gt; {</span>
<span class="pl-c">   *   console.log('After tests');</span>
<span class="pl-c">   * });</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * test('my test', async ({ page }) =&gt; {</span>
<span class="pl-c">   *   // ...</span>
<span class="pl-c">   * });</span>
<span class="pl-c">   * ```</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * <span class="pl-k">@param</span> hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].</span>
<span class="pl-c">   */</span>
  <span class="pl-en">beforeAll</span><span class="pl-kos">(</span><span class="pl-en">inner</span>: <span class="pl-kos">(</span><span class="pl-s1">args</span>: <span class="pl-smi">TestArgs</span> <span class="pl-c1">&amp;</span> <span class="pl-smi">WorkerArgs</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span>: <span class="pl-smi">TestInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=</span><span class="pl-c1">&gt;</span> <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">any</span><span class="pl-kos">&gt;</span> <span class="pl-c1">|</span> <span class="pl-s1">any</span><span class="pl-kos">)</span>: <span class="pl-k">void</span><span class="pl-kos">;</span>
  <span class="pl-c">/**</span>
<span class="pl-c">   * Declares an `afterAll` hook that is executed once per worker after all tests.</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * **Details**</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * When called in the scope of a test file, runs after all tests in the file. When called inside a</span>
<span class="pl-c">   * [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-1) group, runs after all</span>
<span class="pl-c">   * tests in the group. If multiple `afterAll` hooks are added, they will run in the order of their registration.</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * Note that worker process is restarted on test failures, and `afterAll` hook runs again in the new worker. Learn</span>
<span class="pl-c">   * more about [workers and failures](https://playwright.dev/docs/test-retries).</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * **Usage**</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * ```js</span>
<span class="pl-c">   * test.afterAll(async () =&gt; {</span>
<span class="pl-c">   *   console.log('Done with tests');</span>
<span class="pl-c">   *   // ...</span>
<span class="pl-c">   * });</span>
<span class="pl-c">   * ```</span>
<span class="pl-c">   *</span>
<span class="pl-c">   * <span class="pl-k">@param</span> hookFunction Hook function that takes one or two arguments: an object with worker fixtures and optional [TestInfo].</span>
<span class="pl-c">   */</span>
  <span class="pl-en">afterAll</span><span class="pl-kos">(</span><span class="pl-en">inner</span>: <span class="pl-kos">(</span><span class="pl-s1">args</span>: <span class="pl-smi">TestArgs</span> <span class="pl-c1">&amp;</span> <span class="pl-smi">WorkerArgs</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span>: <span class="pl-smi">TestInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=</span><span class="pl-c1">&gt;</span> <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">any</span><span class="pl-kos">&gt;</span> <span class="pl-c1">|</span> <span class="pl-s1">any</span><span class="pl-kos">)</span>: <span class="pl-k">void</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">According <a href="https://playwright.dev/docs/api/class-workerinfo" rel="nofollow">to the documentation</a> the WorkerInfo class is available to beforeAll and afterAll hooks as well as worker scoped fixtures.</p>
<p dir="auto">The docs describing the <a href="https://playwright.dev/docs/api/class-test#test-before-all" rel="nofollow">beforeAll and afterAll hooks</a> contradict the WorkerInfo docs. They probably need updating too.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">A TestInfo type is returned instead of the correct WorkerInfo type.</p>