@toolstackhq/create-qa-patterns 1.0.12 → 1.0.14

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.
Files changed (58) hide show
  1. package/README.md +32 -0
  2. package/index.js +502 -41
  3. package/package.json +1 -1
  4. package/templates/cypress-template/README.md +32 -0
  5. package/templates/cypress-template/allurerc.mjs +10 -0
  6. package/templates/cypress-template/config/README.md +5 -0
  7. package/templates/cypress-template/config/environments.ts +1 -0
  8. package/templates/cypress-template/config/runtime-config.ts +1 -0
  9. package/templates/cypress-template/config/secret-manager.ts +1 -0
  10. package/templates/cypress-template/cypress/e2e/README.md +6 -0
  11. package/templates/cypress-template/cypress/e2e/ui-journey.cy.ts +1 -0
  12. package/templates/cypress-template/cypress/support/README.md +5 -0
  13. package/templates/cypress-template/cypress/support/app-config.ts +1 -0
  14. package/templates/cypress-template/cypress/support/commands.ts +1 -0
  15. package/templates/cypress-template/cypress/support/data/README.md +5 -0
  16. package/templates/cypress-template/cypress/support/data/data-factory.ts +1 -0
  17. package/templates/cypress-template/cypress/support/data/id-generator.ts +1 -0
  18. package/templates/cypress-template/cypress/support/data/seeded-faker.ts +1 -0
  19. package/templates/cypress-template/cypress/support/e2e.ts +1 -0
  20. package/templates/cypress-template/cypress/support/pages/README.md +5 -0
  21. package/templates/cypress-template/cypress/support/pages/login-page.ts +1 -0
  22. package/templates/cypress-template/cypress/support/pages/people-page.ts +1 -0
  23. package/templates/cypress-template/cypress.config.ts +17 -1
  24. package/templates/cypress-template/eslint.config.mjs +1 -1
  25. package/templates/cypress-template/package-lock.json +2857 -109
  26. package/templates/cypress-template/package.json +4 -0
  27. package/templates/cypress-template/scripts/README.md +5 -0
  28. package/templates/cypress-template/scripts/generate-allure-report.mjs +66 -0
  29. package/templates/cypress-template/scripts/run-cypress.mjs +1 -0
  30. package/templates/cypress-template/tsconfig.json +1 -1
  31. package/templates/playwright-template/README.md +20 -0
  32. package/templates/playwright-template/components/README.md +5 -0
  33. package/templates/playwright-template/config/README.md +5 -0
  34. package/templates/playwright-template/config/environments.ts +1 -0
  35. package/templates/playwright-template/config/runtime-config.ts +1 -0
  36. package/templates/playwright-template/config/secret-manager.ts +1 -0
  37. package/templates/playwright-template/data/factories/README.md +6 -0
  38. package/templates/playwright-template/data/factories/data-factory.ts +1 -0
  39. package/templates/playwright-template/data/generators/README.md +5 -0
  40. package/templates/playwright-template/data/generators/id-generator.ts +1 -0
  41. package/templates/playwright-template/data/generators/seeded-faker.ts +1 -0
  42. package/templates/playwright-template/fixtures/README.md +5 -0
  43. package/templates/playwright-template/fixtures/test-fixtures.ts +1 -0
  44. package/templates/playwright-template/pages/README.md +6 -0
  45. package/templates/playwright-template/pages/base-page.ts +1 -0
  46. package/templates/playwright-template/pages/login-page.ts +1 -0
  47. package/templates/playwright-template/pages/people-page.ts +1 -0
  48. package/templates/playwright-template/playwright.config.ts +1 -0
  49. package/templates/playwright-template/reporters/README.md +5 -0
  50. package/templates/playwright-template/reporters/structured-reporter.ts +1 -0
  51. package/templates/playwright-template/scripts/README.md +5 -0
  52. package/templates/playwright-template/scripts/generate-allure-report.mjs +1 -0
  53. package/templates/playwright-template/tests/README.md +7 -0
  54. package/templates/playwright-template/tests/api-people.spec.ts +1 -0
  55. package/templates/playwright-template/tests/ui-journey.spec.ts +1 -0
  56. package/templates/playwright-template/utils/README.md +5 -0
  57. package/templates/playwright-template/utils/logger.ts +1 -0
  58. package/templates/playwright-template/utils/test-step.ts +1 -0
@@ -11,6 +11,8 @@
11
11
  "demo:ui": "node ./demo-apps/ui-demo-app/src/server.js",
12
12
  "lint": "eslint .",
13
13
  "typecheck": "tsc --noEmit",
14
+ "report:allure": "node ./scripts/generate-allure-report.mjs",
15
+ "report:allure:open": "allure open reports/allure",
14
16
  "ci": "bash ./scripts/run-tests.sh"
15
17
  },
16
18
  "dependencies": {
@@ -24,6 +26,8 @@
24
26
  "@types/node": "^22.7.4",
25
27
  "@typescript-eslint/eslint-plugin": "^8.8.1",
26
28
  "@typescript-eslint/parser": "^8.8.1",
29
+ "allure": "^3.3.1",
30
+ "allure-cypress": "^3.3.3",
27
31
  "cypress": "^13.17.0",
28
32
  "eslint": "^9.12.0",
29
33
  "typescript": "^5.6.2"
@@ -0,0 +1,5 @@
1
+ # Scripts
2
+
3
+ This folder contains local runner helpers for the Cypress template.
4
+
5
+ - Keep automation entrypoints here so package scripts stay small.
@@ -0,0 +1,66 @@
1
+ // Builds a local Allure report from raw test results after a test run completes.
2
+ import { AllureReport, readConfig } from "@allurereport/core";
3
+ import { readdir, rm, stat } from "node:fs/promises";
4
+ import { join, resolve } from "node:path";
5
+ import process from "node:process";
6
+
7
+ const cwd = process.cwd();
8
+ const resultsDir = resolve(cwd, "allure-results");
9
+ const outputDir = resolve(cwd, "reports/allure");
10
+
11
+ const collectResultFiles = async () => {
12
+ const entries = (await readdir(resultsDir)).sort();
13
+ const files = [];
14
+
15
+ for (const entry of entries) {
16
+ const filePath = join(resultsDir, entry);
17
+ const entryStat = await stat(filePath);
18
+
19
+ if (entryStat.isFile()) {
20
+ files.push(filePath);
21
+ }
22
+ }
23
+
24
+ return files;
25
+ };
26
+
27
+ const generateReport = async () => {
28
+ try {
29
+ await stat(resultsDir);
30
+ } catch {
31
+ process.stdout.write("Skipping Allure report generation because allure-results does not exist.\n");
32
+ return;
33
+ }
34
+
35
+ const files = await collectResultFiles();
36
+
37
+ if (files.length === 0) {
38
+ process.stdout.write("Skipping Allure report generation because no result files were found.\n");
39
+ return;
40
+ }
41
+
42
+ await rm(outputDir, { force: true, recursive: true });
43
+
44
+ const config = await readConfig(cwd, "allurerc.mjs", { output: outputDir });
45
+ const report = new AllureReport(config);
46
+
47
+ await report.start();
48
+
49
+ for (const file of files) {
50
+ await report.readFile(file);
51
+ }
52
+
53
+ await report.done();
54
+
55
+ process.stdout.write("Allure report generated at reports/allure/index.html\n");
56
+ };
57
+
58
+ generateReport().catch((error) => {
59
+ if (error instanceof Error) {
60
+ process.stderr.write(`${error.message}\n`);
61
+ } else {
62
+ process.stderr.write(`${String(error)}\n`);
63
+ }
64
+
65
+ process.exit(1);
66
+ });
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Starts the local demo app when needed, then launches Cypress in run or open mode.
3
4
  import process from "node:process";
4
5
  import path from "node:path";
5
6
  import { spawn } from "node:child_process";
@@ -11,5 +11,5 @@
11
11
  "noEmit": true,
12
12
  "types": ["cypress", "node"]
13
13
  },
14
- "include": ["cypress/**/*.ts", "cypress/**/*.d.ts", "config/**/*.ts", "cypress.config.ts"]
14
+ "include": ["cypress/**/*.ts", "cypress/**/*.d.ts", "config/**/*.ts", "cypress.config.ts", "allurerc.mjs"]
15
15
  }
@@ -13,6 +13,7 @@ This is a Playwright + TypeScript automation framework template for UI and API t
13
13
  - [Reports and artifacts](#reports-and-artifacts)
14
14
  - [Add a new test](#add-a-new-test)
15
15
  - [Extend the framework](#extend-the-framework)
16
+ - [Template upgrades](#template-upgrades)
16
17
  - [CI and Docker](#ci-and-docker)
17
18
 
18
19
  ## Feature set
@@ -21,6 +22,7 @@ This is a Playwright + TypeScript automation framework template for UI and API t
21
22
  - page object pattern with selectors kept out of tests
22
23
  - shared fixtures for config, logging, data, and page objects
23
24
  - generic data factory pattern with `DataFactory`
25
+ - folder-level `README.md` guides and file-header comments for easier onboarding
24
26
  - multi-environment runtime config with `dev`, `staging`, and `prod`
25
27
  - env-based secret resolution with a replaceable `SecretProvider`
26
28
  - Playwright HTML report by default
@@ -227,6 +229,24 @@ Recommended rules:
227
229
  - prefer semantic selectors such as `getByRole`, `getByLabel`, and `data-testid`
228
230
  - keep the data layer generic until the project really needs domain-specific factories
229
231
 
232
+ ## Template upgrades
233
+
234
+ This project includes a `.qa-patterns.json` metadata file so future CLI versions can compare the current project against the managed template baseline.
235
+
236
+ Check for available safe updates:
237
+
238
+ ```bash
239
+ npx -y @toolstackhq/create-qa-patterns upgrade check .
240
+ ```
241
+
242
+ Apply only safe managed-file updates:
243
+
244
+ ```bash
245
+ npx -y @toolstackhq/create-qa-patterns upgrade apply --safe .
246
+ ```
247
+
248
+ The upgrade flow is conservative. It updates framework infrastructure such as config, scripts, workflows, and package metadata when those files are still unchanged from the generated baseline. If you changed a managed file yourself, the CLI reports a conflict instead of overwriting it.
249
+
230
250
  ## CI and Docker
231
251
 
232
252
  The CI entrypoint is:
@@ -0,0 +1,5 @@
1
+ # Components
2
+
3
+ This folder holds reusable UI fragments shared by multiple pages.
4
+
5
+ - Use components for repeated widgets such as flash messages or shared panels.
@@ -0,0 +1,5 @@
1
+ # Config
2
+
3
+ This folder resolves environment-specific runtime values.
4
+
5
+ - Keep environment defaults, secret lookup, and runtime parsing here.
@@ -1,3 +1,4 @@
1
+ // Defines the built-in environment defaults used when env vars are not provided.
1
2
  import type { TestEnvironment } from "./test-env";
2
3
 
3
4
  type EnvironmentDefaults = {
@@ -1,3 +1,4 @@
1
+ // Builds the runtime configuration object that tests and fixtures consume.
1
2
  import path from "node:path";
2
3
 
3
4
  import dotenv from "dotenv";
@@ -1,3 +1,4 @@
1
+ // Minimal secret abstraction so env-based secrets can later be replaced cleanly.
1
2
  import type { TestEnvironment } from "./test-env";
2
3
 
3
4
  export interface SecretProvider {
@@ -0,0 +1,6 @@
1
+ # Factories
2
+
3
+ This folder exposes small, readable builders for test data.
4
+
5
+ - Start generic.
6
+ - Add domain-specific builders only when the project needs them.
@@ -1,3 +1,4 @@
1
+ // Generic data builders that keep tests readable and deterministic.
1
2
  import { createSeededFaker } from "../generators/seeded-faker";
2
3
  import { IdGenerator } from "../generators/id-generator";
3
4
 
@@ -0,0 +1,5 @@
1
+ # Generators
2
+
3
+ This folder contains low-level helpers that factories build on.
4
+
5
+ - Keep seeded randomness and id generation here.
@@ -1,3 +1,4 @@
1
+ // Deterministic id generator for repeatable local and CI runs.
1
2
  export class IdGenerator {
2
3
  private readonly counters = new Map<string, number>();
3
4
 
@@ -1,3 +1,4 @@
1
+ // Seeded faker wrapper so generated values stay stable for a given run id.
1
2
  import { Faker, en } from "@faker-js/faker";
2
3
 
3
4
  function hashSeed(value: string): number {
@@ -0,0 +1,5 @@
1
+ # Fixtures
2
+
3
+ This folder wires together the objects that tests consume.
4
+
5
+ - Put shared setup, config loading, and page creation here.
@@ -1,3 +1,4 @@
1
+ // Shared Playwright fixtures so tests can stay small and focus on behavior.
1
2
  import { test as base } from "@playwright/test";
2
3
 
3
4
  import { loadRuntimeConfig, type RuntimeConfig } from "../config/runtime-config";
@@ -0,0 +1,6 @@
1
+ # Pages
2
+
3
+ This folder holds Playwright page objects.
4
+
5
+ - Page classes own locators and UI actions.
6
+ - Tests should talk to these classes instead of raw selectors.
@@ -1,3 +1,4 @@
1
+ // Base page with shared helpers that concrete page objects can build on.
1
2
  import type { Page } from "@playwright/test";
2
3
 
3
4
  import { FlashMessage } from "../components/flash-message";
@@ -1,3 +1,4 @@
1
+ // Page object for the login screen and its user actions.
1
2
  import type { Page } from "@playwright/test";
2
3
 
3
4
  import type { Logger } from "../utils/logger";
@@ -1,3 +1,4 @@
1
+ // Page object for the people screen used in the starter UI workflow.
1
2
  import type { Page } from "@playwright/test";
2
3
 
3
4
  import type { PersonRecord } from "../data/factories/data-factory";
@@ -1,3 +1,4 @@
1
+ // Central Playwright configuration for local runs, CI, reporters, and demo app startup.
1
2
  import { defineConfig, devices } from "@playwright/test";
2
3
 
3
4
  import { loadRuntimeConfig } from "./config/runtime-config";
@@ -0,0 +1,5 @@
1
+ # Reporters
2
+
3
+ This folder contains custom Playwright reporters.
4
+
5
+ - Use these when you need machine-readable output in addition to built-in reports.
@@ -1,3 +1,4 @@
1
+ // Custom reporter that writes machine-readable test lifecycle events to disk.
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
4
 
@@ -0,0 +1,5 @@
1
+ # Scripts
2
+
3
+ This folder contains helper scripts used by local development and CI.
4
+
5
+ - Keep shell and Node entrypoints here instead of inside workflow files.
@@ -1,3 +1,4 @@
1
+ // Builds a local Allure report from raw test results after a test run completes.
1
2
  import { AllureReport, readConfig } from "@allurereport/core";
2
3
  import { readdir, rm, stat } from "node:fs/promises";
3
4
  import { join, resolve } from "node:path";
@@ -0,0 +1,7 @@
1
+ # Tests
2
+
3
+ This folder holds user-facing Playwright scenarios.
4
+
5
+ - Keep tests focused on behavior and business flow.
6
+ - Use fixtures from `../fixtures/test-fixtures`.
7
+ - Keep selectors out of test files.
@@ -1,3 +1,4 @@
1
+ // Starter API journey that pairs with the deterministic demo API server.
1
2
  import { expect, test } from "../fixtures/test-fixtures";
2
3
 
3
4
  test.describe("API starter flow", () => {
@@ -1,3 +1,4 @@
1
+ // Starter UI journey that shows the preferred Playwright test style in this template.
1
2
  import { expect, test } from "../fixtures/test-fixtures";
2
3
 
3
4
  test.describe("UI starter journey", () => {
@@ -0,0 +1,5 @@
1
+ # Utils
2
+
3
+ This folder holds small framework helpers.
4
+
5
+ - Put generic logging and step wrappers here.
@@ -1,3 +1,4 @@
1
+ // Structured JSON logger used by tests, pages, and helper classes.
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
4
 
@@ -1,3 +1,4 @@
1
+ // Small wrapper that records named test steps in a consistent way.
1
2
  import { test } from "@playwright/test";
2
3
 
3
4
  import type { Logger } from "./logger";