Skip to content

Commit d88519a

Browse files
author
Nikita Filonov
committed
remove context
1 parent d98396a commit d88519a

File tree

5 files changed

+49
-47
lines changed

5 files changed

+49
-47
lines changed

README.md

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -301,72 +301,87 @@ const tracker = new UICoverageTracker({ app: 'my-ui-app' });
301301

302302
### Advanced Example
303303

304-
This example demonstrates how to use `ui-coverage-scenario-tool-js` with execution context to automatically track UI
305-
coverage scenarios in Playwright — without manually passing the tracker through every layer of your app.
304+
This example demonstrates how to use `ui-coverage-scenario-tool-js` with a manual context based on `WeakMap` — ideal
305+
when you prefer to avoid Node.js-specific features like `AsyncLocalStorage`, or want to keep the tracker tied directly
306+
to the Page object.
306307

307-
#### Step 1: Initialize the tracker
308+
#### Step 1: Initialize the tracker storage
308309

309-
Create a single instance of `UICoverageTracker` that will be shared across all tests.
310+
Instead of a global singleton tracker or implicit context, we use a `WeakMap` to associate a `UICoverageTracker` with
311+
each Playwright `Page` instance.
310312

311313
`./coverage.ts`
312314

313315
```typescript
314316
import { UICoverageTracker } from 'ui-coverage-scenario-tool-js';
317+
import type { Page } from '@playwright/test';
315318

316-
export const tracker = new UICoverageTracker({ app: 'ui-course' });
319+
// Map from Playwright Page to its UI coverage tracker
320+
export const trackerByPage = new WeakMap<Page, UICoverageTracker>();
317321
```
318322

319-
#### Step 2: Extend Playwright’s test with scenario setup and teardown
323+
#### Step 2: Extend Playwright’s test with setup and teardown
320324

321-
Create a custom test wrapper where:
325+
Wrap Playwright’s test to:
322326

323-
- the scenario is started before each test (with a name and a link to an external TMS),
324-
- and ended after the test is complete.
327+
- create and register a new tracker for each test,
328+
- start a scenario before the test begins,
329+
- and end it after the test completes.
325330

326331
`./tests/base.ts`
327332

328333
```typescript
329334
import { test as base } from '@playwright/test';
330-
import { coverageContext } from 'ui-coverage-scenario-tool-js';
331-
import { tracker } from '../coverage';
335+
import { trackerByPage } from '../coverage';
336+
import { UICoverageTracker } from 'ui-coverage-scenario-tool-js';
332337

333338
export const test = base.extend<{}>({
334339
async page({ page }, use, testInfo) {
335-
coverageContext.run(tracker, () => {
336-
tracker.startScenario({
337-
url: `https://company.tms.com/testcases/${testInfo.testId}`, // link to external test case
338-
name: testInfo.title
339-
});
340+
// Create a new tracker for this test
341+
const tracker = new UICoverageTracker({ app: 'ui-course' });
342+
343+
// Start the scenario with test name and external link
344+
tracker.startScenario({
345+
name: testInfo.title,
346+
url: `https://company.tms.com/testcases/${testInfo.testId}` // link to external test case
340347
});
341348

349+
// Associate the tracker with this page instance
350+
trackerByPage.set(page, tracker);
351+
352+
// Run the test
342353
await use(page);
343354

344-
await coverageContext.get()?.endScenario();
355+
// Finalize scenario and clean up
356+
await tracker.endScenario();
357+
trackerByPage.delete(page); // important: cleanup to avoid leaks
345358
}
346359
});
347360
```
348361

349-
_This uses `AsyncLocalStorage` internally to propagate the tracker across async calls — you don’t need to pass it
350-
manually._
351-
352362
#### Step 3: Track interactions inside PageObjects
353363

354-
Inside your PageObject or UI component, simply call `coverageContext.get()` to record interactions:
364+
Inside your PageObjects (or components), retrieve the tracker via `trackerByPage` using the current `Page`, and use it
365+
to track user interactions.
355366

356367
`./pages/login-page.ts`
357368

358369
```typescript
359370
import { Page } from '@playwright/test';
360-
import { ActionType, coverageContext, SelectorType } from 'ui-coverage-scenario-tool-js';
371+
import { ActionType, SelectorType } from 'ui-coverage-scenario-tool-js';
372+
import { trackerByPage } from '../coverage';
361373

362374
export class LoginPage {
363375
constructor(private page: Page) {
364376
}
365377

366378
async clickLoginButton() {
379+
// Perform actual UI interaction
367380
await this.page.click('#login');
368381

369-
await coverageContext.get()?.trackCoverage({
382+
// Track the interaction with the coverage tool
383+
const tracker = trackerByPage.get(this.page);
384+
tracker?.trackCoverage({
370385
selector: '#login',
371386
actionType: ActionType.Click,
372387
selectorType: SelectorType.CSS
@@ -375,9 +390,9 @@ export class LoginPage {
375390
}
376391
```
377392

378-
#### Step 4: Writing tests
393+
#### Step 4: Write clean tests
379394

380-
Now your test stays clean and focused — and coverage tracking happens behind the scenes.
395+
Now your tests remain clean and focused — and coverage tracking happens behind the scenes via `WeakMap`.
381396

382397
`./tests/important-feature.spec.ts`
383398

@@ -391,12 +406,13 @@ test('Should login via the login button', async ({ page }) => {
391406
});
392407
```
393408

394-
#### Why this matters
409+
#### Why this approach works
395410

396-
- Context-aware tracking — no need to manually pass the tracker around.
397-
- Scenario binding — each interaction is tied to the test that triggered it.
398-
- TMS integration — easily associate scenarios with external test cases or tickets.
399-
- Parallel-safe — works reliably even with concurrent test execution.
411+
- **Context-aware tracking** — without relying on Node.js internals.
412+
- **Explicit association** — tracker is tied directly to the Playwright `Page`.
413+
- **Scenario binding** — each test has its own isolated tracker and scenario.
414+
- **Parallel-safe** — works reliably even with concurrent test execution.
415+
- **Browser-compatible** — works in environments that lack AsyncLocalStorage.
400416

401417
### Coverage Report Generation
402418

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ui-coverage-scenario-tool-js",
3-
"version": "0.5.0",
3+
"version": "0.7.0",
44
"type": "module",
55
"files": [
66
"dist",

src/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const program = new Command();
77
program
88
.name('ui-coverage-scenario-tool')
99
.description('UI Coverage Scenario CLI Tool')
10-
.version('0.5.0');
10+
.version('0.7.0');
1111

1212
program
1313
.command('save-report')

src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
export { ActionType } from './tools/actions';
22
export { SelectorType } from './tools/selector';
3-
export { UICoverageTracker } from './tracker/core';
4-
export { coverageContext } from './tracker/context';
3+
export { UICoverageTracker } from './tracker/core';

src/tracker/context.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)