@toolstackhq/create-qa-patterns 1.0.6 → 1.0.7
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 +15 -2
- package/index.js +130 -48
- package/package.json +1 -1
- package/templates/cypress-template/.env.example +5 -0
- package/templates/cypress-template/.github/workflows/cypress-tests.yml +47 -0
- package/templates/cypress-template/README.md +195 -0
- package/templates/cypress-template/config/environments.ts +37 -0
- package/templates/cypress-template/config/runtime-config.ts +46 -0
- package/templates/cypress-template/config/secret-manager.ts +19 -0
- package/templates/cypress-template/config/test-env.ts +13 -0
- package/templates/cypress-template/cypress/e2e/ui-journey.cy.ts +20 -0
- package/templates/cypress-template/cypress/support/app-config.ts +23 -0
- package/templates/cypress-template/cypress/support/commands.d.ts +15 -0
- package/templates/cypress-template/cypress/support/commands.ts +17 -0
- package/templates/cypress-template/cypress/support/data/data-factory.ts +33 -0
- package/templates/cypress-template/cypress/support/data/id-generator.ts +13 -0
- package/templates/cypress-template/cypress/support/data/seeded-faker.ts +11 -0
- package/templates/cypress-template/cypress/support/e2e.ts +1 -0
- package/templates/cypress-template/cypress/support/pages/login-page.ts +23 -0
- package/templates/cypress-template/cypress/support/pages/people-page.ts +59 -0
- package/templates/cypress-template/cypress.config.ts +32 -0
- package/templates/cypress-template/demo-apps/ui-demo-app/package.json +10 -0
- package/templates/cypress-template/demo-apps/ui-demo-app/public/styles.css +120 -0
- package/templates/cypress-template/demo-apps/ui-demo-app/src/server.js +149 -0
- package/templates/cypress-template/demo-apps/ui-demo-app/src/store.js +43 -0
- package/templates/cypress-template/demo-apps/ui-demo-app/src/templates.js +121 -0
- package/templates/cypress-template/eslint.config.mjs +93 -0
- package/templates/cypress-template/package-lock.json +3758 -0
- package/templates/cypress-template/package.json +31 -0
- package/templates/cypress-template/scripts/run-cypress.mjs +105 -0
- package/templates/cypress-template/scripts/run-tests.sh +6 -0
- package/templates/cypress-template/tsconfig.json +15 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
function layout({ title, body, flashMessage = "", username = "tester" }) {
|
|
2
|
+
return `<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>${title}</title>
|
|
8
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div class="layout">
|
|
12
|
+
<header class="header">
|
|
13
|
+
<div class="brand">UI Patterns Demo</div>
|
|
14
|
+
<nav class="nav" aria-label="Primary">
|
|
15
|
+
<a href="/people">People</a>
|
|
16
|
+
</nav>
|
|
17
|
+
</header>
|
|
18
|
+
${flashMessage ? `<div class="flash-message" data-testid="flash-message" role="status">${flashMessage}</div>` : ""}
|
|
19
|
+
<p data-testid="welcome-message">Signed in as ${username}</p>
|
|
20
|
+
${body}
|
|
21
|
+
</div>
|
|
22
|
+
</body>
|
|
23
|
+
</html>`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function loginPage(errorMessage = "") {
|
|
27
|
+
return `<!DOCTYPE html>
|
|
28
|
+
<html lang="en">
|
|
29
|
+
<head>
|
|
30
|
+
<meta charset="UTF-8" />
|
|
31
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
32
|
+
<title>Login</title>
|
|
33
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
34
|
+
</head>
|
|
35
|
+
<body>
|
|
36
|
+
<main class="login-shell">
|
|
37
|
+
<section class="card login-card">
|
|
38
|
+
<h1>Login</h1>
|
|
39
|
+
<p>Keep the example intentionally small: sign in, add one person, assert the list.</p>
|
|
40
|
+
${errorMessage ? `<div class="flash-message" role="status">${errorMessage}</div>` : ""}
|
|
41
|
+
<form action="/login" method="post">
|
|
42
|
+
<label for="username">
|
|
43
|
+
Username
|
|
44
|
+
<input id="username" name="username" type="text" autocomplete="username" required />
|
|
45
|
+
</label>
|
|
46
|
+
<label for="password">
|
|
47
|
+
Password
|
|
48
|
+
<input id="password" name="password" type="password" autocomplete="current-password" required />
|
|
49
|
+
</label>
|
|
50
|
+
<button type="submit">Sign in</button>
|
|
51
|
+
</form>
|
|
52
|
+
</section>
|
|
53
|
+
</main>
|
|
54
|
+
</body>
|
|
55
|
+
</html>`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function peoplePage(people) {
|
|
59
|
+
const rows = people
|
|
60
|
+
.map((person) => {
|
|
61
|
+
return `<tr data-testid="person-row-${person.personId}">
|
|
62
|
+
<td>${person.name}</td>
|
|
63
|
+
<td>${person.role}</td>
|
|
64
|
+
<td>${person.email}</td>
|
|
65
|
+
</tr>`;
|
|
66
|
+
})
|
|
67
|
+
.join("");
|
|
68
|
+
|
|
69
|
+
return `
|
|
70
|
+
<section class="panel-grid">
|
|
71
|
+
<section class="panel">
|
|
72
|
+
<h1>People</h1>
|
|
73
|
+
<form action="/people" method="post">
|
|
74
|
+
<label for="personId">
|
|
75
|
+
Person ID
|
|
76
|
+
<input id="personId" name="personId" type="text" required />
|
|
77
|
+
</label>
|
|
78
|
+
<label for="name">
|
|
79
|
+
Name
|
|
80
|
+
<input id="name" name="name" type="text" required />
|
|
81
|
+
</label>
|
|
82
|
+
<label for="role">
|
|
83
|
+
Role
|
|
84
|
+
<input id="role" name="role" type="text" required />
|
|
85
|
+
</label>
|
|
86
|
+
<label for="email">
|
|
87
|
+
Email
|
|
88
|
+
<input id="email" name="email" type="email" required />
|
|
89
|
+
</label>
|
|
90
|
+
<button type="submit">Add person</button>
|
|
91
|
+
</form>
|
|
92
|
+
</section>
|
|
93
|
+
<section class="panel">
|
|
94
|
+
<h2>Directory</h2>
|
|
95
|
+
<form action="/people" method="get">
|
|
96
|
+
<label for="search">
|
|
97
|
+
Search
|
|
98
|
+
<input id="search" name="search" type="text" placeholder="Search people" />
|
|
99
|
+
</label>
|
|
100
|
+
<button type="submit">Apply filter</button>
|
|
101
|
+
</form>
|
|
102
|
+
<table>
|
|
103
|
+
<thead>
|
|
104
|
+
<tr>
|
|
105
|
+
<th>Name</th>
|
|
106
|
+
<th>Role</th>
|
|
107
|
+
<th>Email</th>
|
|
108
|
+
</tr>
|
|
109
|
+
</thead>
|
|
110
|
+
<tbody>${rows}</tbody>
|
|
111
|
+
</table>
|
|
112
|
+
</section>
|
|
113
|
+
</section>
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
layout,
|
|
119
|
+
loginPage,
|
|
120
|
+
peoplePage
|
|
121
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tsParser from "@typescript-eslint/parser";
|
|
3
|
+
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
|
4
|
+
|
|
5
|
+
const cypressGlobals = {
|
|
6
|
+
Cypress: "readonly",
|
|
7
|
+
cy: "readonly",
|
|
8
|
+
describe: "readonly",
|
|
9
|
+
it: "readonly",
|
|
10
|
+
before: "readonly",
|
|
11
|
+
beforeEach: "readonly",
|
|
12
|
+
after: "readonly",
|
|
13
|
+
afterEach: "readonly"
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const nodeGlobals = {
|
|
17
|
+
process: "readonly",
|
|
18
|
+
console: "readonly"
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default [
|
|
22
|
+
{
|
|
23
|
+
ignores: ["demo-apps/**", "node_modules/**", "reports/**"]
|
|
24
|
+
},
|
|
25
|
+
js.configs.recommended,
|
|
26
|
+
{
|
|
27
|
+
files: ["**/*.ts"],
|
|
28
|
+
languageOptions: {
|
|
29
|
+
parser: tsParser,
|
|
30
|
+
parserOptions: {
|
|
31
|
+
project: "./tsconfig.json"
|
|
32
|
+
},
|
|
33
|
+
globals: {
|
|
34
|
+
...cypressGlobals,
|
|
35
|
+
...nodeGlobals
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
plugins: {
|
|
39
|
+
"@typescript-eslint": tsPlugin
|
|
40
|
+
},
|
|
41
|
+
rules: {
|
|
42
|
+
...tsPlugin.configs.recommended.rules,
|
|
43
|
+
"no-undef": "off",
|
|
44
|
+
"@typescript-eslint/no-unused-vars": [
|
|
45
|
+
"error",
|
|
46
|
+
{
|
|
47
|
+
argsIgnorePattern: "^_",
|
|
48
|
+
varsIgnorePattern: "^_"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
files: ["scripts/**/*.mjs"],
|
|
55
|
+
languageOptions: {
|
|
56
|
+
globals: {
|
|
57
|
+
...nodeGlobals,
|
|
58
|
+
fetch: "readonly",
|
|
59
|
+
setTimeout: "readonly"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
files: ["cypress/e2e/**/*.ts"],
|
|
65
|
+
rules: {
|
|
66
|
+
"no-restricted-properties": [
|
|
67
|
+
"error",
|
|
68
|
+
{
|
|
69
|
+
object: "cy",
|
|
70
|
+
property: "get",
|
|
71
|
+
message: "Keep selectors in support/page modules or custom commands, not in spec files."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
object: "cy",
|
|
75
|
+
property: "contains",
|
|
76
|
+
message: "Keep selectors in support/page modules or custom commands, not in spec files."
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
files: ["cypress/support/pages/**/*.ts"],
|
|
83
|
+
rules: {
|
|
84
|
+
"no-restricted-syntax": [
|
|
85
|
+
"error",
|
|
86
|
+
{
|
|
87
|
+
selector: "CallExpression[callee.name='expect']",
|
|
88
|
+
message: "Keep assertions in Cypress spec files."
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
];
|