@checksum-ai/runtime 1.0.3 → 1.0.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.
@@ -0,0 +1 @@
1
+ Checksum readme
@@ -0,0 +1,56 @@
1
+ import { RunMode, getChecksumConfig } from "@checksum-ai/runtime";
2
+
3
+ export default getChecksumConfig({
4
+ /**
5
+ * Checksum runtime running mode -
6
+ * normal - tests run normally
7
+ * heal - checksum will attempt to heal tests that failed using fallback
8
+ * refactor - checksum will attempt to refactor and improve your tests
9
+ */
10
+ runMode: RunMode.Normal,
11
+
12
+ /**
13
+ * Insert here your Checksum API key
14
+ */
15
+ apiKey: "<API key>",
16
+
17
+ /**
18
+ * This is the base URL of the tested app
19
+ */
20
+ baseURL: "<base URL>",
21
+
22
+ /**
23
+ * Insert the account's username that will be used
24
+ * to login into your testing environment
25
+ */
26
+ username: "<username>",
27
+
28
+ /**
29
+ * Insert the account's password that will be used
30
+ * to login into your testing environment
31
+ */
32
+ password: "<password>",
33
+
34
+ options: {
35
+ /**
36
+ * Whether to fallback to ESRA if the action selector is not found
37
+ */
38
+ actionsESRAfallback: true,
39
+
40
+ /**
41
+ * Whether to use LLM fallback if action selector is not found
42
+ */
43
+ actionsLLMFallback: true,
44
+
45
+ /**
46
+ * Whether to use mock API data when running your tests
47
+ */
48
+ useMockData: false,
49
+
50
+ /**
51
+ * Print runtime logs.
52
+ * Use for debug only
53
+ */
54
+ printLogs: false,
55
+ },
56
+ });
@@ -0,0 +1,19 @@
1
+ import { ChecksumConfig, IChecksumPage } from "@checksum-ai/runtime";
2
+
3
+ /**
4
+ * Login method
5
+ */
6
+ export default async function login(
7
+ page: IChecksumPage,
8
+ config: ChecksumConfig
9
+ ) {
10
+ /**
11
+ * Update this function to login to your application
12
+ * i.e.:
13
+ * await page.goto('/login');
14
+ * await page.getByPlaceholder("Email...").fill(config.username);
15
+ * await page.getByPlaceholder("Password...").fill(config.password);
16
+ * await page.getByText("Continue").click();
17
+ * await page.waitForURL("/main");
18
+ */
19
+ }
@@ -0,0 +1,32 @@
1
+ import { defineConfig, devices } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ timeout: 120000,
5
+ testMatch: [/.*.[.]checksum.spec.ts/],
6
+ testDir: ".",
7
+ /* disable parallel test runs */
8
+ workers: 1,
9
+ /* Run tests in files in parallel */
10
+ fullyParallel: false,
11
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
12
+ reporter: "html",
13
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
14
+ use: {
15
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
16
+ trace: "on",
17
+ video: "on",
18
+ },
19
+
20
+ /* Configure projects for major browsers */
21
+ projects: [
22
+ {
23
+ name: "chromium",
24
+ use: { ...devices["Desktop Chrome"] },
25
+ },
26
+ {
27
+ name: "checksumpage",
28
+ use: { ...devices["Desktop Chrome"] },
29
+ testDir: "./src/lib/runtime",
30
+ },
31
+ ],
32
+ });
package/cli.ts ADDED
@@ -0,0 +1,225 @@
1
+ import { copyFileSync, existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
2
+ import * as childProcess from "child_process";
3
+ import { join } from "path";
4
+
5
+ const ROOT_DIR_NAME = "checksum";
6
+
7
+ class ChecksumCLI {
8
+ checksumConfig = undefined;
9
+
10
+ constructor() {}
11
+
12
+ async execute() {
13
+ switch (process.argv[2]) {
14
+ case "install":
15
+ this.install();
16
+ break;
17
+ case "run":
18
+ if (process.argv?.[3] === "--help") {
19
+ await this.printHelp("run");
20
+ break;
21
+ }
22
+ await this.run(process.argv.slice(3));
23
+ break;
24
+ default:
25
+ await this.printHelp();
26
+ }
27
+ process.exit(0);
28
+ }
29
+
30
+ async execCmd(cmdString) {
31
+ const child = await childProcess.spawn(cmdString, {
32
+ shell: true,
33
+ stdio: "inherit",
34
+ });
35
+
36
+ const exitPromise = new Promise((resolve, reject) => {
37
+ child.on("exit", (code) => {
38
+ if (code === 0) {
39
+ resolve(true);
40
+ } else {
41
+ reject(
42
+ new Error(
43
+ `Checsum failed execution with code: ${code} for command: "${cmdString}`
44
+ )
45
+ );
46
+ }
47
+ });
48
+ });
49
+
50
+ return exitPromise;
51
+ }
52
+
53
+ async getCmdOutput(cmdString): Promise<string> {
54
+ return new Promise<string>(function (resolve, reject) {
55
+ childProcess.exec(cmdString, (error, stdout, stderr) => {
56
+ if (error) {
57
+ reject(`Error executing command: ${error.message}`);
58
+ return;
59
+ }
60
+
61
+ resolve(stdout);
62
+ });
63
+ });
64
+
65
+ // return promise;
66
+ }
67
+
68
+ async printHelp(command?: string) {
69
+ switch (command) {
70
+ default:
71
+ console.log(`
72
+ Checksum CLI
73
+ Usage: checksum [command] [options]
74
+
75
+ Commands:
76
+ install installs checksum files and folders
77
+ run runs checksum tests
78
+ help prints this help message
79
+ `);
80
+ break;
81
+ case "run":
82
+ try {
83
+ const cmd = `npx playwright test --help`;
84
+ const testHelp: string = await this.getCmdOutput(cmd);
85
+ console.log(
86
+ testHelp.replace(/npx playwright test/g, "yarn checksum run")
87
+ );
88
+ } catch (e) {
89
+ console.log("Error", e.message);
90
+ }
91
+
92
+ break;
93
+ }
94
+ }
95
+
96
+ async run(args: string[]) {
97
+ args = this.getChecksumConfig(args);
98
+ // run shell command and pipe output rhe response to console
99
+ const cmd = `npx playwright test --config ${join(
100
+ this.getRootDirPath(),
101
+ "playwright.config.ts"
102
+ )} ${args.join(" ")}`;
103
+
104
+ try {
105
+ this.buildVolatileConfig();
106
+ return this.execCmd(cmd);
107
+ } catch (e) {
108
+ console.log("Error", e.message);
109
+ } finally {
110
+ this.cleanup();
111
+ }
112
+ }
113
+
114
+ buildVolatileConfig() {
115
+ if (!this.checksumConfig) {
116
+ return;
117
+ }
118
+
119
+ const configPath = this.getVolatileConfigPath();
120
+ const configString = `
121
+ import { RunMode, getChecksumConfig } from "@checksum-ai/runtime";
122
+
123
+ export default getChecksumConfig(${JSON.stringify(
124
+ this.checksumConfig,
125
+ null,
126
+ 2
127
+ )});
128
+ `;
129
+
130
+ writeFileSync(configPath, configString);
131
+ }
132
+
133
+ cleanup() {
134
+ const configPath = this.getVolatileConfigPath();
135
+ if (existsSync(configPath)) {
136
+ rmSync(configPath);
137
+ }
138
+ }
139
+
140
+ getVolatileConfigPath() {
141
+ return join(this.getRootDirPath(), "checksum.config.tmp.ts");
142
+ }
143
+
144
+ getChecksumConfig(args) {
145
+ for (const arg of args) {
146
+ if (arg.startsWith("--checksum-config")) {
147
+ try {
148
+ this.checksumConfig = JSON.parse(arg.split("=")[1]);
149
+ return args.filter((a) => a !== arg);
150
+ } catch (e) {
151
+ console.log("Error parsing checksum config", e.message);
152
+ this.checksumConfig = undefined;
153
+ }
154
+ }
155
+ }
156
+
157
+ return args;
158
+ }
159
+
160
+ install() {
161
+ console.log(
162
+ "Creating Checksum directory and necessary files to run your tests"
163
+ );
164
+
165
+ const checksumRoot = this.getRootDirPath();
166
+
167
+ if (!existsSync(this.getRootDirPath())) {
168
+ mkdirSync(checksumRoot);
169
+ }
170
+
171
+ if (!existsSync(this.getChecksumRootOrigin())) {
172
+ throw new Error(
173
+ "Could not find checksum root directory, please install @checksum-ai/runtime package"
174
+ );
175
+
176
+ // automatically install?
177
+ }
178
+
179
+ // copy sources
180
+ [
181
+ "checksum.config.ts",
182
+ "playwright.config.ts",
183
+ "login.ts",
184
+ "README.md",
185
+ ].forEach((file) => {
186
+ copyFileSync(
187
+ join(this.getChecksumRootOrigin(), file),
188
+ join(checksumRoot, file)
189
+ );
190
+ });
191
+
192
+ // create tests folder
193
+ mkdirSync(join(checksumRoot, "tests"), {
194
+ recursive: true,
195
+ });
196
+
197
+ // create test data directories
198
+ ["esra", "har", "trace", "log"].forEach((folder) => {
199
+ mkdirSync(join(checksumRoot, "test-data", folder), {
200
+ recursive: true,
201
+ });
202
+ });
203
+ }
204
+
205
+ getRootDirPath() {
206
+ return join(process.cwd(), ROOT_DIR_NAME);
207
+ }
208
+
209
+ getChecksumRootOrigin() {
210
+ return join(
211
+ process.cwd(),
212
+ "node_modules",
213
+ "@checksum-ai",
214
+ "runtime",
215
+ "checksum-root"
216
+ );
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Trigger the main function
222
+ */
223
+ (async () => {
224
+ await new ChecksumCLI().execute();
225
+ })();