qa-intelligence 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,158 +12,49 @@ The intelligence engine for Playwright CI pipelines — install it into any proj
12
12
 
13
13
  Use it **without the framework template** — install the package into your existing app repo.
14
14
 
15
- **Recommended layout:** create a `playwright/` subfolder at the repo root and keep all E2E tooling there, separate from your main app code. Full step-by-step guide (folder layout, `Dockerfile`, CI path changes): **[qa-intelligence-framework README](https://github.com/ardithaqi/qa-intelligence-framework#add-to-an-existing-project-npm-package)**.
16
15
 
17
16
  ---
18
17
 
19
- ## Install
18
+ ## Quick start
20
19
 
21
- Run inside your `playwright/` folder (or your Playwright project root if tests already live there):
20
+ Run from your **repo root** (not inside `playwright/`). You do **not** need a `playwright/` folder beforehand `init` creates it.
22
21
 
23
22
  ```bash
23
+ npx qa-intelligence init
24
24
  cd playwright
25
- npm install qa-intelligence @playwright/test
25
+ cp .env.example .env # set BASE_URL
26
+ npm install # installs qa-intelligence + @playwright/test (see playwright/package.json)
27
+ npx playwright install
26
28
  ```
27
29
 
28
- npm automatically installs peer dependencies (`typescript`, `@types/node`) — no separate dev-deps step needed.
30
+ `init` scaffolds:
29
31
 
30
- ---
31
-
32
- ## Setup
33
-
34
- All paths below are relative to `playwright/` when using the recommended subfolder layout.
35
-
36
- ### 1. Environment (`.env`)
37
-
38
- ```env
39
- BASE_URL=https://your-app.example.com
40
- HEADLESS=true
41
- PW_WORKERS=2
42
- PW_RETRIES=1
43
- ```
32
+ - `playwright/` — `.env.example`, `package.json`, `tsconfig.json`, `playwright.config.ts`, example test
33
+ - `.github/workflows/qa-intelligence.yml` — PR diff, history, and comment (skip with `--no-ci`)
44
34
 
45
- ### 2. `tsconfig.json` (TypeScript projects)
46
-
47
- ```json
48
- {
49
- "compilerOptions": {
50
- "target": "ES2022",
51
- "module": "Node16",
52
- "moduleResolution": "Node16",
53
- "strict": true,
54
- "esModuleInterop": true,
55
- "types": ["node"],
56
- "skipLibCheck": true
57
- },
58
- "include": ["tests/**/*", "playwright.config.ts"]
59
- }
60
- ```
61
-
62
- > `module` and `moduleResolution` must both be `"Node16"` so TypeScript resolves the package `exports` map.
35
+ **Then:** add `OPENAI_API_KEY` to GitHub secrets and set `BASE_URL` in the workflow file.
63
36
 
64
- ### 3. `playwright.config.ts`
65
-
66
- ```ts
67
- import { defineConfig } from "@playwright/test";
68
- import { env } from "qa-intelligence/config/env";
69
-
70
- export default defineConfig({
71
- testDir: "./tests",
72
- retries: env.PW_RETRIES,
73
- workers: env.PW_WORKERS,
74
- globalSetup: require.resolve("qa-intelligence/playwright/globalSetup"),
75
- globalTeardown: require.resolve("qa-intelligence/playwright/globalTeardown"),
76
- use: {
77
- baseURL: env.BASE_URL,
78
- headless: env.HEADLESS,
79
- trace: "on-first-retry",
80
- screenshot: "only-on-failure",
81
- video: "retain-on-failure",
82
- },
83
- });
84
- ```
85
-
86
- ### 4. Write tests
87
-
88
- **Important** — always import `test` and `expect` from the package:
37
+ **Tests** always import from the package, not Playwright directly:
89
38
 
90
39
  ```ts
91
40
  import { test, expect } from "qa-intelligence/playwright";
92
41
  ```
93
42
 
94
- **Not** directly from Playwright:
95
-
96
- ```ts
97
- // ❌ No AI artifacts, no PR diff, no flaky detection
98
- import { test, expect } from "@playwright/test";
99
- ```
100
-
101
- Using `qa-intelligence/playwright` enables:
102
-
103
- - AI failure analysis (`meta.json` → `ai.txt`)
104
- - Artifact generation on failure
105
- - Flaky detection (retry-aware)
106
- - CI diff intelligence and PR comments
107
-
108
- Example test:
109
-
110
- ```ts
111
- import { test, expect } from "qa-intelligence/playwright";
112
-
113
- test("user can login", async ({ page }) => {
114
- await page.goto("/");
115
- await expect(page).toHaveTitle(/My App/);
116
- });
117
- ```
43
+ ### `init` options
118
44
 
119
- > **Using the [framework template](https://github.com/ardithaqi/qa-intelligence-framework)?** Import from local `src/core/baseTest` instead same hooks, different path for that repo layout.
45
+ By default, `init` skips any file that already exists so it won't overwrite your work.
120
46
 
121
- Optional helpers:
47
+ | Flag | What it does |
48
+ |------|----------------|
49
+ | `--no-ci` | Only scaffold `playwright/` (config, env, tests). Does **not** create `.github/workflows/qa-intelligence.yml`. Use this if you already have CI or use GitLab/Jenkins. |
50
+ | `--force` | Overwrite existing scaffold files. Use when re-running `init` and you want a fresh copy from the templates. |
122
51
 
123
- ```ts
124
- import { step } from "qa-intelligence/playwright/steps";
125
- import { BasePage } from "qa-intelligence/playwright/basePage";
52
+ ```bash
53
+ npx qa-intelligence init # playwright/ + GitHub workflow
54
+ npx qa-intelligence init --no-ci # playwright/ only
55
+ npx qa-intelligence init --force # overwrite files that already exist
126
56
  ```
127
57
 
128
- ### 5. What you provide
129
-
130
- | You write | Package provides |
131
- |-----------|------------------|
132
- | `playwright/tests/` | Test hooks, artifact capture |
133
- | `playwright/.env` | Env validation |
134
- | `playwright/playwright.config.ts` | `globalSetup`, `globalTeardown`, AI teardown |
135
- | `playwright/Dockerfile` | — (copy from [framework](https://github.com/ardithaqi/qa-intelligence-framework/blob/master/Dockerfile)) |
136
- | `.github/workflows/ci.yml` | `qa-intelligence-diff`, `qa-intelligence-history`, `qa-intelligence-comment` |
137
- | Page objects (optional) | `BasePage`, `step()` |
138
-
139
- ---
140
-
141
- ## CI setup (GitHub Actions)
142
-
143
- Copy [`.github/workflows/ci.yml`](https://github.com/ardithaqi/qa-intelligence-framework/blob/master/.github/workflows/ci.yml) and [`Dockerfile`](https://github.com/ardithaqi/qa-intelligence-framework/blob/master/Dockerfile) from the framework repo.
144
-
145
- When using the `playwright/` subfolder layout, apply the CI path changes documented in the [framework adoption guide](https://github.com/ardithaqi/qa-intelligence-framework#add-to-an-existing-project-npm-package) (`working-directory: playwright`, artifact paths, etc.).
146
-
147
- The workflow includes:
148
-
149
- - Docker test execution
150
- - Artifact upload on every run
151
- - Baseline download from `main` on pull requests
152
- - `qa-intelligence-diff`, `qa-intelligence-history`, `qa-intelligence-comment`
153
- - PR blocking on new non-flaky failures
154
-
155
- Then update:
156
-
157
- - `BASE_URL` in the `docker run` step
158
- - GitHub secrets (see below)
159
-
160
- ### Required GitHub secrets
161
-
162
- - `OPENAI_API_KEY` — enables AI failure analysis in teardown
163
- - `TEST_USERNAME` / `TEST_PASSWORD` — if your tests need credentials
164
-
165
- Set `AI_ANALYSIS=true` in CI when running tests inside Docker.
166
-
167
58
  ---
168
59
 
169
60
  ## PR behavior
@@ -177,20 +68,21 @@ Set `AI_ANALYSIS=true` in CI when running tests inside Docker.
177
68
 
178
69
  ---
179
70
 
180
- ## CLI tools
71
+ ## CLI
181
72
 
182
73
  | Command | Purpose |
183
74
  |---------|---------|
75
+ | `qa-intelligence init` | Scaffold project files |
184
76
  | `qa-intelligence-diff` | Compare baseline vs current failures |
185
- | `qa-intelligence-history` | Add recurrence tracking |
186
- | `qa-intelligence-comment` | Post/update PR summary comment |
77
+ | `qa-intelligence-history` | Recurrence tracking |
78
+ | `qa-intelligence-comment` | Post/update PR summary |
187
79
 
188
80
  ---
189
81
 
190
82
  ## Package exports
191
83
 
192
- | Import path | What it gives you |
193
- |-------------|-------------------|
84
+ | Import | What you get |
85
+ |--------|--------------|
194
86
  | `qa-intelligence/playwright` | `test`, `expect`, `env` |
195
87
  | `qa-intelligence/playwright/globalSetup` | Artifact run setup |
196
88
  | `qa-intelligence/playwright/globalTeardown` | AI failure analysis |
@@ -200,19 +92,11 @@ Set `AI_ANALYSIS=true` in CI when running tests inside Docker.
200
92
 
201
93
  ---
202
94
 
203
- ## Alternative: use the full template
204
-
205
- If you prefer a ready-made project with examples, Docker, and CI pre-wired:
206
-
207
- **[qa-intelligence-framework](https://github.com/ardithaqi/qa-intelligence-framework)** — click "Use this template".
208
-
209
- The template uses this package under the hood.
210
-
211
- ---
95
+ ## Full template (optional)
212
96
 
213
- ## Author
97
+ Prefer a ready-made project with Docker, example tests, and CI pre-wired? Use the **[qa-intelligence-framework](https://github.com/ardithaqi/qa-intelligence-framework)** template — click "Use this template".
214
98
 
215
- Built as the intelligence engine behind QA automation Playwright hooks, AI failure analysis, and PR-aware CI. If you use this package, consider leaving a star or linking back—contributions are welcome.
99
+ For adding to an existing repo with a `playwright/` subfolder, see the [framework adoption guide](https://github.com/ardithaqi/qa-intelligence-framework#add-to-an-existing-project-npm-package) (`Dockerfile`, CI path changes).
216
100
 
217
101
  ---
218
102
 
package/dist/cli/index.js CHANGED
@@ -1,5 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
4
37
  const child_process_1 = require("child_process");
5
38
  function getArg(name) {
@@ -9,6 +42,12 @@ function getArg(name) {
9
42
  return process.argv[idx + 1];
10
43
  }
11
44
  async function main() {
45
+ const subcommand = process.argv[2];
46
+ if (subcommand === "init") {
47
+ const { main: runInit } = await Promise.resolve().then(() => __importStar(require("./init")));
48
+ await runInit();
49
+ return;
50
+ }
12
51
  const baseline = getArg("baseline") ?? "baseline-artifacts";
13
52
  const current = getArg("current") ?? "artifacts";
14
53
  const repo = getArg("repo");
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ export declare function runInit(options?: {
3
+ root?: string;
4
+ force?: boolean;
5
+ withCi?: boolean;
6
+ }): {
7
+ written: string[];
8
+ skipped: string[];
9
+ };
10
+ export declare function main(): Promise<void>;
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.runInit = runInit;
8
+ exports.main = main;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const PLAYWRIGHT_SCAFFOLD = [
12
+ { template: "playwright/.env.example", dest: "playwright/.env.example" },
13
+ { template: "playwright/tsconfig.json", dest: "playwright/tsconfig.json" },
14
+ {
15
+ template: "playwright/playwright.config.ts",
16
+ dest: "playwright/playwright.config.ts",
17
+ },
18
+ { template: "playwright/package.json", dest: "playwright/package.json" },
19
+ {
20
+ template: "playwright/tests/example.spec.ts",
21
+ dest: "playwright/tests/example.spec.ts",
22
+ },
23
+ ];
24
+ const CI_SCAFFOLD = [
25
+ {
26
+ template: "github/workflows/qa-intelligence.yml",
27
+ dest: ".github/workflows/qa-intelligence.yml",
28
+ },
29
+ ];
30
+ function hasFlag(name) {
31
+ return process.argv.includes(`--${name}`);
32
+ }
33
+ function templatesDir() {
34
+ return path_1.default.join(__dirname, "..", "..", "templates");
35
+ }
36
+ function copyScaffold(root, entries, force) {
37
+ const written = [];
38
+ const skipped = [];
39
+ const sourceRoot = templatesDir();
40
+ for (const { template, dest } of entries) {
41
+ const source = path_1.default.join(sourceRoot, template);
42
+ const target = path_1.default.join(root, dest);
43
+ if (!fs_1.default.existsSync(source)) {
44
+ throw new Error(`Missing template: ${template}`);
45
+ }
46
+ if (fs_1.default.existsSync(target) && !force) {
47
+ skipped.push(dest);
48
+ continue;
49
+ }
50
+ fs_1.default.mkdirSync(path_1.default.dirname(target), { recursive: true });
51
+ fs_1.default.copyFileSync(source, target);
52
+ written.push(dest);
53
+ }
54
+ return { written, skipped };
55
+ }
56
+ function runInit(options) {
57
+ const root = path_1.default.resolve(options?.root ?? process.cwd());
58
+ const force = options?.force ?? false;
59
+ const withCi = options?.withCi ?? true;
60
+ const entries = [...PLAYWRIGHT_SCAFFOLD];
61
+ if (withCi) {
62
+ entries.push(...CI_SCAFFOLD);
63
+ }
64
+ return copyScaffold(root, entries, force);
65
+ }
66
+ async function main() {
67
+ const force = hasFlag("force");
68
+ const noCi = hasFlag("no-ci");
69
+ console.log("Scaffolding qa-intelligence in:", process.cwd());
70
+ const { written, skipped } = runInit({
71
+ force,
72
+ withCi: !noCi,
73
+ });
74
+ for (const file of written) {
75
+ console.log(` created ${file}`);
76
+ }
77
+ for (const file of skipped) {
78
+ console.log(` skipped ${file} (exists — use --force to overwrite)`);
79
+ }
80
+ if (written.length === 0 && skipped.length > 0) {
81
+ console.log("\nNothing new was written.");
82
+ return;
83
+ }
84
+ console.log("\nNext steps:");
85
+ console.log(" 1. cd playwright && cp .env.example .env # set BASE_URL");
86
+ console.log(" 2. cd playwright && npm install");
87
+ console.log(" 3. npx playwright install");
88
+ console.log(" 4. Add OPENAI_API_KEY to GitHub repo secrets (for CI)");
89
+ if (!noCi) {
90
+ console.log(" 5. Update BASE_URL in .github/workflows/qa-intelligence.yml");
91
+ }
92
+ console.log(" 6. Write tests — import from qa-intelligence/playwright");
93
+ }
94
+ if (require.main === module) {
95
+ main().catch((e) => {
96
+ console.error(e);
97
+ process.exit(1);
98
+ });
99
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qa-intelligence",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },
@@ -57,6 +57,7 @@
57
57
  },
58
58
  "bin": {
59
59
  "qa-intelligence": "dist/cli/index.js",
60
+ "qa-intelligence-init": "dist/cli/init.js",
60
61
  "qa-intelligence-diff": "dist/cli/diff.js",
61
62
  "qa-intelligence-history": "dist/cli/history.js",
62
63
  "qa-intelligence-comment": "dist/cli/postComment.js"
@@ -82,6 +83,7 @@
82
83
  "typescript": "^5.9.3"
83
84
  },
84
85
  "files": [
85
- "dist"
86
+ "dist",
87
+ "templates"
86
88
  ]
87
89
  }
@@ -0,0 +1,129 @@
1
+ name: QA Intelligence CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ permissions:
10
+ contents: read
11
+ actions: read
12
+ issues: write
13
+ pull-requests: write
14
+
15
+ jobs:
16
+ test:
17
+ runs-on: ubuntu-latest
18
+ defaults:
19
+ run:
20
+ working-directory: playwright
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-node@v4
26
+ with:
27
+ node-version: 20
28
+
29
+ - name: Install dependencies
30
+ run: npm install
31
+
32
+ - name: Install Playwright browsers
33
+ run: npx playwright install --with-deps chromium
34
+
35
+ - name: Clean artifacts
36
+ if: always()
37
+ run: rm -rf artifacts
38
+
39
+ - name: Run Playwright tests
40
+ env:
41
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
42
+ AI_ANALYSIS: true
43
+ BASE_URL: https://your-app.example.com
44
+ HEADLESS: true
45
+ PW_WORKERS: 2
46
+ PW_RETRIES: 1
47
+ TEST_USERNAME: ${{ secrets.TEST_USERNAME }}
48
+ TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
49
+ run: |
50
+ set +e
51
+ npx playwright test
52
+ EXIT=$?
53
+ if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then exit 0; fi
54
+ exit $EXIT
55
+
56
+ - name: Upload Playwright HTML report
57
+ if: always()
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: playwright-report
61
+ path: playwright/playwright-report/
62
+
63
+ - name: Upload AI failure artifacts
64
+ if: always()
65
+ uses: actions/upload-artifact@v4
66
+ with:
67
+ name: ai-failure-artifacts
68
+ path: playwright/artifacts/
69
+
70
+ - name: Parse AI failure reports
71
+ if: always()
72
+ run: |
73
+ echo "Parsing AI failure reports..."
74
+ if [ -d "artifacts" ]; then
75
+ find artifacts -name "ai.txt" | while read file; do
76
+ echo "-----"
77
+ echo "File: $file"
78
+ json=$(awk '/^{/{flag=1} flag' "$file")
79
+ echo "$json" | jq .
80
+ done
81
+ else
82
+ echo "No artifacts directory found."
83
+ fi
84
+
85
+ - name: Download baseline artifacts from main
86
+ if: always() && github.event_name == 'pull_request'
87
+ uses: dawidd6/action-download-artifact@v6
88
+ with:
89
+ workflow: qa-intelligence.yml
90
+ branch: ${{ github.base_ref }}
91
+ name: ai-failure-artifacts
92
+ path: baseline-artifacts
93
+ if_no_artifact_found: warn
94
+
95
+ - name: Debug baseline contents
96
+ if: always() && github.event_name == 'pull_request'
97
+ run: |
98
+ echo "Baseline:"
99
+ ls -la ../baseline-artifacts || true
100
+ echo "Current:"
101
+ ls -la artifacts || true
102
+
103
+ - name: Compute failure diff
104
+ if: always() && github.event_name == 'pull_request'
105
+ run: npx qa-intelligence-diff --baseline ../baseline-artifacts --current artifacts
106
+
107
+ - name: Restore failure history cache
108
+ if: always() && github.event_name == 'pull_request'
109
+ uses: actions/cache@v4
110
+ with:
111
+ path: playwright/.cache
112
+ key: failure-history-${{ github.repository }}-${{ github.sha }}
113
+ restore-keys: |
114
+ failure-history-${{ github.repository }}-
115
+
116
+ - name: Update failure history (recurrence)
117
+ if: always() && github.event_name == 'pull_request'
118
+ run: npx qa-intelligence-history
119
+
120
+ - name: Comment PR with AI summary
121
+ if: always() && github.event_name == 'pull_request'
122
+ env:
123
+ GITHUB_TOKEN: ${{ github.token }}
124
+ run: |
125
+ npx qa-intelligence-comment \
126
+ --diff failure-diff.json \
127
+ --repo ${{ github.repository }} \
128
+ --pr ${{ github.event.pull_request.number }} \
129
+ --token $GITHUB_TOKEN
@@ -0,0 +1,8 @@
1
+ BASE_URL=https://your-app.example.com
2
+ HEADLESS=true
3
+ PW_WORKERS=2
4
+ PW_RETRIES=1
5
+
6
+ # Optional — enable AI failure analysis in teardown
7
+ # OPENAI_API_KEY=sk-...
8
+ # AI_ANALYSIS=true
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "e2e-tests",
3
+ "private": true,
4
+ "scripts": {
5
+ "test": "playwright test"
6
+ },
7
+ "dependencies": {
8
+ "@playwright/test": "^1.58.0",
9
+ "qa-intelligence": "^1.1.4"
10
+ }
11
+ }
@@ -0,0 +1,18 @@
1
+ import { defineConfig } from "@playwright/test";
2
+ import { env } from "qa-intelligence/config/env";
3
+
4
+ export default defineConfig({
5
+ testDir: "./tests",
6
+ retries: env.PW_RETRIES,
7
+ workers: env.PW_WORKERS,
8
+ globalSetup: require.resolve("qa-intelligence/playwright/globalSetup"),
9
+ globalTeardown: require.resolve("qa-intelligence/playwright/globalTeardown"),
10
+ use: {
11
+ baseURL: env.BASE_URL,
12
+ headless: env.HEADLESS,
13
+ trace: "on-first-retry",
14
+ screenshot: "only-on-failure",
15
+ video: "retain-on-failure",
16
+ },
17
+ reporter: [["html", { open: "never" }]],
18
+ });
@@ -0,0 +1,6 @@
1
+ import { test, expect } from "qa-intelligence/playwright";
2
+
3
+ test("example — replace with your first test", async ({ page }) => {
4
+ await page.goto("/");
5
+ await expect(page).toHaveTitle(/.*/);
6
+ });
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "types": ["node"],
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["tests/**/*", "playwright.config.ts"]
12
+ }