@browserstack/mcp-server 1.2.5 → 1.2.6
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/apiClient.d.ts +2 -1
- package/dist/lib/apiClient.js +2 -1
- package/dist/lib/inmemory-store.d.ts +5 -1
- package/dist/lib/inmemory-store.js +10 -1
- package/dist/lib/version-resolver.js +4 -0
- package/dist/tools/add-percy-snapshots.d.ts +0 -1
- package/dist/tools/add-percy-snapshots.js +11 -6
- package/dist/tools/automate-utils/fetch-screenshots.js +4 -1
- package/dist/tools/list-test-files.d.ts +1 -1
- package/dist/tools/list-test-files.js +43 -19
- package/dist/tools/percy-sdk.js +3 -3
- package/dist/tools/percy-snapshot-utils/constants.d.ts +0 -6
- package/dist/tools/percy-snapshot-utils/constants.js +0 -15
- package/dist/tools/rca-agent-utils/constants.d.ts +1 -1
- package/dist/tools/rca-agent-utils/constants.js +2 -2
- package/dist/tools/rca-agent-utils/rca-data.d.ts +1 -1
- package/dist/tools/rca-agent-utils/rca-data.js +2 -2
- package/dist/tools/rca-agent-utils/types.d.ts +3 -3
- package/dist/tools/rca-agent.d.ts +1 -1
- package/dist/tools/run-percy-scan.js +51 -10
- package/dist/tools/sdk-utils/bstack/configUtils.d.ts +2 -1
- package/dist/tools/sdk-utils/bstack/configUtils.js +9 -2
- package/dist/tools/sdk-utils/bstack/constants.d.ts +1 -1
- package/dist/tools/sdk-utils/bstack/constants.js +7 -9
- package/dist/tools/sdk-utils/bstack/sdkHandler.js +11 -9
- package/dist/tools/sdk-utils/common/constants.d.ts +1 -1
- package/dist/tools/sdk-utils/common/constants.js +1 -1
- package/dist/tools/sdk-utils/common/device-validator.js +7 -0
- package/dist/tools/sdk-utils/common/schema.d.ts +8 -4
- package/dist/tools/sdk-utils/common/schema.js +5 -0
- package/dist/tools/sdk-utils/common/utils.d.ts +1 -1
- package/dist/tools/sdk-utils/common/utils.js +12 -1
- package/dist/tools/sdk-utils/handler.js +19 -2
- package/dist/tools/sdk-utils/percy-automate/constants.d.ts +4 -4
- package/dist/tools/sdk-utils/percy-bstack/constants.d.ts +4 -4
- package/dist/tools/sdk-utils/percy-bstack/handler.js +1 -1
- package/dist/tools/sdk-utils/percy-web/constants.d.ts +22 -20
- package/dist/tools/sdk-utils/percy-web/constants.js +39 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/lib/apiClient.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ type RequestOptions = {
|
|
|
5
5
|
params?: Record<string, string | number>;
|
|
6
6
|
body?: any;
|
|
7
7
|
timeout?: number;
|
|
8
|
+
responseType?: AxiosRequestConfig["responseType"];
|
|
8
9
|
raise_error?: boolean;
|
|
9
10
|
};
|
|
10
11
|
declare class ApiResponse<T = any> {
|
|
@@ -23,7 +24,7 @@ declare class ApiClient {
|
|
|
23
24
|
private get axiosAgent();
|
|
24
25
|
private validateUrl;
|
|
25
26
|
private requestWrapper;
|
|
26
|
-
get<T = any>({ url, headers, params, timeout, raise_error, }: RequestOptions): Promise<ApiResponse<T>>;
|
|
27
|
+
get<T = any>({ url, headers, params, timeout, responseType, raise_error, }: RequestOptions): Promise<ApiResponse<T>>;
|
|
27
28
|
post<T = any>({ url, headers, body, timeout, raise_error, }: RequestOptions): Promise<ApiResponse<T>>;
|
|
28
29
|
put<T = any>({ url, headers, body, timeout, raise_error, }: RequestOptions): Promise<ApiResponse<T>>;
|
|
29
30
|
patch<T = any>({ url, headers, body, timeout, raise_error, }: RequestOptions): Promise<ApiResponse<T>>;
|
package/dist/lib/apiClient.js
CHANGED
|
@@ -120,11 +120,12 @@ class ApiClient {
|
|
|
120
120
|
throw error;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
async get({ url, headers, params, timeout, raise_error = true, }) {
|
|
123
|
+
async get({ url, headers, params, timeout, responseType, raise_error = true, }) {
|
|
124
124
|
const config = {
|
|
125
125
|
headers,
|
|
126
126
|
params,
|
|
127
127
|
timeout,
|
|
128
|
+
responseType,
|
|
128
129
|
httpsAgent: this.axiosAgent,
|
|
129
130
|
};
|
|
130
131
|
return this.requestWrapper(() => this.instance.get(url, config), url, config, raise_error);
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
export const signedUrlMap = new Map();
|
|
2
|
-
|
|
2
|
+
let _storedPercyResults = null;
|
|
3
|
+
export const storedPercyResults = {
|
|
4
|
+
get: () => _storedPercyResults,
|
|
5
|
+
set: (value) => {
|
|
6
|
+
_storedPercyResults = value;
|
|
7
|
+
},
|
|
8
|
+
clear: () => {
|
|
9
|
+
_storedPercyResults = null;
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -24,6 +24,10 @@ export function resolveVersion(requested, available) {
|
|
|
24
24
|
if (uniq.includes(requested)) {
|
|
25
25
|
return requested;
|
|
26
26
|
}
|
|
27
|
+
const caseInsensitiveMatch = uniq.find((v) => v.toLowerCase() === requested.toLowerCase());
|
|
28
|
+
if (caseInsensitiveMatch) {
|
|
29
|
+
return caseInsensitiveMatch;
|
|
30
|
+
}
|
|
27
31
|
// Try major version matching (e.g., "14" matches "14.0", "14.1", etc.)
|
|
28
32
|
const reqNum = parseFloat(requested);
|
|
29
33
|
if (!isNaN(reqNum)) {
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { storedPercyResults } from "../lib/inmemory-store.js";
|
|
2
2
|
import { updateFileAndStep } from "./percy-snapshot-utils/utils.js";
|
|
3
3
|
import { percyWebSetupInstructions } from "../tools/sdk-utils/percy-web/handler.js";
|
|
4
4
|
export async function updateTestsWithPercyCommands(args) {
|
|
5
|
-
const {
|
|
6
|
-
const
|
|
7
|
-
if (!
|
|
8
|
-
throw new Error(`No test files found in memory
|
|
5
|
+
const { index } = args;
|
|
6
|
+
const stored = storedPercyResults.get();
|
|
7
|
+
if (!stored || !stored.testFiles) {
|
|
8
|
+
throw new Error(`No test files found in memory. Please call listTestFiles first.`);
|
|
9
9
|
}
|
|
10
|
+
const fileStatusMap = stored.testFiles;
|
|
11
|
+
const filePaths = Object.keys(fileStatusMap);
|
|
10
12
|
if (index < 0 || index >= filePaths.length) {
|
|
11
|
-
throw new Error(`Invalid index: ${index}. There are ${filePaths.length} files
|
|
13
|
+
throw new Error(`Invalid index: ${index}. There are ${filePaths.length} files available.`);
|
|
12
14
|
}
|
|
13
15
|
const result = await updateFileAndStep(filePaths[index], index, filePaths.length, percyWebSetupInstructions);
|
|
16
|
+
const updatedStored = { ...stored };
|
|
17
|
+
updatedStored.testFiles[filePaths[index]] = true; // true = updated
|
|
18
|
+
storedPercyResults.set(updatedStored);
|
|
14
19
|
return {
|
|
15
20
|
content: result,
|
|
16
21
|
};
|
|
@@ -39,7 +39,10 @@ async function extractScreenshotUrls(sessionId, sessionType, config) {
|
|
|
39
39
|
//Converts screenshot URLs to base64 encoded images
|
|
40
40
|
async function convertUrlsToBase64(urls) {
|
|
41
41
|
const screenshots = await Promise.all(urls.map(async (url) => {
|
|
42
|
-
const response = await apiClient.get({
|
|
42
|
+
const response = await apiClient.get({
|
|
43
|
+
url,
|
|
44
|
+
responseType: "arraybuffer",
|
|
45
|
+
});
|
|
43
46
|
// Axios returns response.data as a Buffer for binary data
|
|
44
47
|
const base64 = Buffer.from(response.data).toString("base64");
|
|
45
48
|
// Compress the base64 image if needed
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
-
export declare function addListTestFiles(
|
|
2
|
+
export declare function addListTestFiles(): Promise<CallToolResult>;
|
|
@@ -1,35 +1,59 @@
|
|
|
1
1
|
import { listTestFiles } from "./percy-snapshot-utils/detect-test-files.js";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (!
|
|
8
|
-
throw new Error("No
|
|
2
|
+
import { storedPercyResults } from "../lib/inmemory-store.js";
|
|
3
|
+
import { updateFileAndStep } from "./percy-snapshot-utils/utils.js";
|
|
4
|
+
import { percyWebSetupInstructions } from "./sdk-utils/percy-web/handler.js";
|
|
5
|
+
export async function addListTestFiles() {
|
|
6
|
+
const storedResults = storedPercyResults.get();
|
|
7
|
+
if (!storedResults) {
|
|
8
|
+
throw new Error("No Framework details found. Please call expandPercyVisualTesting first to fetch the framework details.");
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const language = storedResults.detectedLanguage;
|
|
11
|
+
const framework = storedResults.detectedTestingFramework;
|
|
12
|
+
// Use stored paths from setUpPercy
|
|
13
|
+
const dirs = storedResults.folderPaths;
|
|
14
|
+
const files = storedResults.filePaths;
|
|
15
|
+
let testFiles = [];
|
|
16
|
+
if (files && files.length > 0) {
|
|
16
17
|
testFiles = testFiles.concat(files);
|
|
17
18
|
}
|
|
19
|
+
if (dirs && dirs.length > 0) {
|
|
20
|
+
for (const dir of dirs) {
|
|
21
|
+
const discoveredFiles = await listTestFiles({
|
|
22
|
+
language,
|
|
23
|
+
framework,
|
|
24
|
+
baseDir: dir,
|
|
25
|
+
});
|
|
26
|
+
testFiles = testFiles.concat(discoveredFiles);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Validate that we have at least one test file
|
|
18
30
|
if (testFiles.length === 0) {
|
|
19
|
-
throw new Error("No test files found");
|
|
31
|
+
throw new Error("No test files found. Please provide either specific file paths (files) or directory paths (dirs) containing test files.");
|
|
32
|
+
}
|
|
33
|
+
if (testFiles.length === 1) {
|
|
34
|
+
const result = await updateFileAndStep(testFiles[0], 0, 1, percyWebSetupInstructions);
|
|
35
|
+
return {
|
|
36
|
+
content: result,
|
|
37
|
+
};
|
|
20
38
|
}
|
|
21
|
-
//
|
|
22
|
-
const
|
|
23
|
-
|
|
39
|
+
// For multiple files, store directly in testFiles
|
|
40
|
+
const fileStatusMap = {};
|
|
41
|
+
testFiles.forEach((file) => {
|
|
42
|
+
fileStatusMap[file] = false; // false = not updated, true = updated
|
|
43
|
+
});
|
|
44
|
+
// Update storedPercyResults with test files
|
|
45
|
+
const updatedStored = { ...storedResults };
|
|
46
|
+
updatedStored.testFiles = fileStatusMap;
|
|
47
|
+
storedPercyResults.set(updatedStored);
|
|
24
48
|
return {
|
|
25
49
|
content: [
|
|
26
50
|
{
|
|
27
51
|
type: "text",
|
|
28
|
-
text: `The Test files are stored in memory
|
|
52
|
+
text: `The Test files are stored in memory and the total number of tests files found is ${testFiles.length}.`,
|
|
29
53
|
},
|
|
30
54
|
{
|
|
31
55
|
type: "text",
|
|
32
|
-
text: `You can now use the tool addPercySnapshotCommands to update the test file with Percy commands for visual testing
|
|
56
|
+
text: `You can now use the tool addPercySnapshotCommands to update the test file with Percy commands for visual testing.`,
|
|
33
57
|
},
|
|
34
58
|
],
|
|
35
59
|
};
|
package/dist/tools/percy-sdk.js
CHANGED
|
@@ -8,7 +8,7 @@ import { approveOrDeclinePercyBuild } from "./review-agent-utils/percy-approve-r
|
|
|
8
8
|
import { setUpPercyHandler, simulatePercyChangeHandler, } from "./sdk-utils/handler.js";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { SETUP_PERCY_DESCRIPTION, LIST_TEST_FILES_DESCRIPTION, PERCY_SNAPSHOT_COMMANDS_DESCRIPTION, SIMULATE_PERCY_CHANGE_DESCRIPTION, } from "./sdk-utils/common/constants.js";
|
|
11
|
-
import {
|
|
11
|
+
import { UpdateTestFileWithInstructionsParams } from "./percy-snapshot-utils/constants.js";
|
|
12
12
|
import { RunPercyScanParamsShape, FetchPercyChangesParamsShape, ManagePercyBuildApprovalParamsShape, } from "./sdk-utils/common/schema.js";
|
|
13
13
|
import { handleMCPError } from "../lib/utils.js";
|
|
14
14
|
export function registerPercyTools(server, config) {
|
|
@@ -57,10 +57,10 @@ export function registerPercyTools(server, config) {
|
|
|
57
57
|
return handleMCPError("addPercySnapshotCommands", server, config, error);
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
-
tools.listTestFiles = server.tool("listTestFiles", LIST_TEST_FILES_DESCRIPTION,
|
|
60
|
+
tools.listTestFiles = server.tool("listTestFiles", LIST_TEST_FILES_DESCRIPTION, {}, async () => {
|
|
61
61
|
try {
|
|
62
62
|
trackMCP("listTestFiles", server.server.getClientVersion(), config);
|
|
63
|
-
return addListTestFiles(
|
|
63
|
+
return addListTestFiles();
|
|
64
64
|
}
|
|
65
65
|
catch (error) {
|
|
66
66
|
return handleMCPError("listTestFiles", server, config, error);
|
|
@@ -2,14 +2,8 @@ import { z } from "zod";
|
|
|
2
2
|
import { SDKSupportedLanguage } from "../sdk-utils/common/types.js";
|
|
3
3
|
import { DetectionConfig } from "./types.js";
|
|
4
4
|
export declare const UpdateTestFileWithInstructionsParams: {
|
|
5
|
-
uuid: z.ZodString;
|
|
6
5
|
index: z.ZodNumber;
|
|
7
6
|
};
|
|
8
|
-
export declare const ListTestFilesParamsShape: {
|
|
9
|
-
dirs: z.ZodArray<z.ZodString, "many">;
|
|
10
|
-
language: z.ZodEnum<[string, ...string[]]>;
|
|
11
|
-
framework: z.ZodEnum<[string, ...string[]]>;
|
|
12
|
-
};
|
|
13
7
|
export declare const TEST_FILE_DETECTION: Record<SDKSupportedLanguage, DetectionConfig>;
|
|
14
8
|
export declare const EXCLUDED_DIRS: Set<string>;
|
|
15
9
|
export declare const backendIndicators: RegExp[];
|
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { SDKSupportedLanguages, SDKSupportedTestingFrameworks, } from "../sdk-utils/common/types.js";
|
|
3
2
|
export const UpdateTestFileWithInstructionsParams = {
|
|
4
|
-
uuid: z
|
|
5
|
-
.string()
|
|
6
|
-
.describe("UUID referencing the in-memory array of test file paths"),
|
|
7
3
|
index: z.number().describe("Index of the test file to update"),
|
|
8
4
|
};
|
|
9
|
-
export const ListTestFilesParamsShape = {
|
|
10
|
-
dirs: z
|
|
11
|
-
.array(z.string())
|
|
12
|
-
.describe("Array of directory paths to search for test files"),
|
|
13
|
-
language: z
|
|
14
|
-
.enum(SDKSupportedLanguages)
|
|
15
|
-
.describe("Programming language"),
|
|
16
|
-
framework: z
|
|
17
|
-
.enum(SDKSupportedTestingFrameworks)
|
|
18
|
-
.describe("Testing framework (optional)"),
|
|
19
|
-
};
|
|
20
5
|
export const TEST_FILE_DETECTION = {
|
|
21
6
|
java: {
|
|
22
7
|
extensions: [".java"],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { TestStatus } from "./types.js";
|
|
3
3
|
export declare const FETCH_RCA_PARAMS: {
|
|
4
|
-
testId: z.ZodArray<z.
|
|
4
|
+
testId: z.ZodArray<z.ZodNumber, "many">;
|
|
5
5
|
};
|
|
6
6
|
export declare const GET_BUILD_ID_PARAMS: {
|
|
7
7
|
browserStackProjectName: z.ZodString;
|
|
@@ -2,9 +2,9 @@ import { z } from "zod";
|
|
|
2
2
|
import { TestStatus } from "./types.js";
|
|
3
3
|
export const FETCH_RCA_PARAMS = {
|
|
4
4
|
testId: z
|
|
5
|
-
.array(z.
|
|
5
|
+
.array(z.number().int())
|
|
6
6
|
.max(3)
|
|
7
|
-
.describe("Array of test IDs to fetch RCA data for (maximum 3 IDs). If not provided, use the listTestIds tool get all failed testcases. If more than 3 IDs are provided, only the first 3 will be processed."),
|
|
7
|
+
.describe("Array of integer test IDs to fetch RCA data for (maximum 3 IDs). These must be numeric test IDs, not session IDs or strings. If not provided, use the listTestIds tool to get all failed testcases. If more than 3 IDs are provided, only the first 3 will be processed."),
|
|
8
8
|
};
|
|
9
9
|
export const GET_BUILD_ID_PARAMS = {
|
|
10
10
|
browserStackProjectName: z
|
|
@@ -5,5 +5,5 @@ interface ScanProgressContext {
|
|
|
5
5
|
progressToken?: string | number;
|
|
6
6
|
};
|
|
7
7
|
}
|
|
8
|
-
export declare function getRCAData(testIds:
|
|
8
|
+
export declare function getRCAData(testIds: number[], authString: string, context?: ScanProgressContext): Promise<RCAResponse>;
|
|
9
9
|
export {};
|
|
@@ -66,7 +66,7 @@ async function updateProgress(context, testCases, message) {
|
|
|
66
66
|
: calculateProgress(resolvedCount, testCases.length));
|
|
67
67
|
}
|
|
68
68
|
async function fetchInitialRCA(testId, headers, baseUrl) {
|
|
69
|
-
const url = baseUrl.replace("{testId}", testId);
|
|
69
|
+
const url = baseUrl.replace("{testId}", testId.toString());
|
|
70
70
|
try {
|
|
71
71
|
const response = await fetch(url, { headers });
|
|
72
72
|
if (!response.ok) {
|
|
@@ -125,7 +125,7 @@ async function pollRCAResults(testCases, headers, baseUrl, context, pollInterval
|
|
|
125
125
|
}
|
|
126
126
|
await Promise.allSettled(inProgressCases.map(async (tc) => {
|
|
127
127
|
try {
|
|
128
|
-
const pollUrl = baseUrl.replace("{testId}", tc.id);
|
|
128
|
+
const pollUrl = baseUrl.replace("{testId}", tc.id.toString());
|
|
129
129
|
const response = await fetch(pollUrl, { headers });
|
|
130
130
|
if (!response.ok) {
|
|
131
131
|
const errorText = await response.text();
|
|
@@ -18,7 +18,7 @@ export interface TestRun {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
export interface FailedTestInfo {
|
|
21
|
-
test_id:
|
|
21
|
+
test_id: number;
|
|
22
22
|
test_name: string;
|
|
23
23
|
}
|
|
24
24
|
export declare enum RCAState {
|
|
@@ -34,8 +34,8 @@ export declare enum RCAState {
|
|
|
34
34
|
TIMEOUT = "TIMEOUT"
|
|
35
35
|
}
|
|
36
36
|
export interface RCATestCase {
|
|
37
|
-
id:
|
|
38
|
-
testRunId:
|
|
37
|
+
id: number;
|
|
38
|
+
testRunId: number;
|
|
39
39
|
state: RCAState;
|
|
40
40
|
rcaData?: any;
|
|
41
41
|
}
|
|
@@ -5,7 +5,7 @@ import { TestStatus } from "./rca-agent-utils/types.js";
|
|
|
5
5
|
import { BuildIdArgs } from "./rca-agent-utils/types.js";
|
|
6
6
|
export declare function getBuildIdTool(args: BuildIdArgs, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
7
7
|
export declare function fetchRCADataTool(args: {
|
|
8
|
-
testId:
|
|
8
|
+
testId: number[];
|
|
9
9
|
}, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
10
10
|
export declare function listTestIdsTool(args: {
|
|
11
11
|
buildId: string;
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { getBrowserStackAuth } from "../lib/get-auth.js";
|
|
2
2
|
import { fetchPercyToken } from "./sdk-utils/percy-web/fetchPercyToken.js";
|
|
3
|
+
import { storedPercyResults } from "../lib/inmemory-store.js";
|
|
4
|
+
import { getFrameworkTestCommand, PERCY_FALLBACK_STEPS, } from "./sdk-utils/percy-web/constants.js";
|
|
5
|
+
import path from "path";
|
|
3
6
|
export async function runPercyScan(args, config) {
|
|
4
7
|
const { projectName, integrationType, instruction } = args;
|
|
5
8
|
const authorization = getBrowserStackAuth(config);
|
|
6
9
|
const percyToken = await fetchPercyToken(projectName, authorization, {
|
|
7
10
|
type: integrationType,
|
|
8
11
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
// Check if we have stored data and project matches
|
|
13
|
+
const stored = storedPercyResults.get();
|
|
14
|
+
// Compute if we have updated files to run
|
|
15
|
+
const hasUpdatedFiles = checkForUpdatedFiles(stored, projectName);
|
|
16
|
+
const updatedFiles = hasUpdatedFiles ? getUpdatedFiles(stored) : [];
|
|
17
|
+
// Build steps array with conditional spread
|
|
18
|
+
const steps = [
|
|
19
|
+
generatePercyTokenInstructions(percyToken),
|
|
20
|
+
...(hasUpdatedFiles ? generateUpdatedFilesSteps(stored, updatedFiles) : []),
|
|
21
|
+
...(instruction && !hasUpdatedFiles
|
|
22
|
+
? generateInstructionSteps(instruction)
|
|
23
|
+
: []),
|
|
24
|
+
...(!hasUpdatedFiles ? PERCY_FALLBACK_STEPS : []),
|
|
25
|
+
];
|
|
19
26
|
const instructionContext = steps
|
|
20
27
|
.map((step, index) => `${index + 1}. ${step}`)
|
|
21
28
|
.join("\n\n");
|
|
@@ -35,3 +42,37 @@ export PERCY_TOKEN="${percyToken}"
|
|
|
35
42
|
|
|
36
43
|
(For Windows: use 'setx PERCY_TOKEN "${percyToken}"' or 'set PERCY_TOKEN=${percyToken}' as appropriate.)`;
|
|
37
44
|
}
|
|
45
|
+
const toAbs = (p) => p ? path.resolve(p) : undefined;
|
|
46
|
+
function checkForUpdatedFiles(stored, // storedPercyResults structure
|
|
47
|
+
projectName) {
|
|
48
|
+
const projectMatches = stored?.projectName === projectName;
|
|
49
|
+
return (projectMatches &&
|
|
50
|
+
stored?.testFiles &&
|
|
51
|
+
Object.values(stored.testFiles).some((status) => status === true));
|
|
52
|
+
}
|
|
53
|
+
function getUpdatedFiles(stored) {
|
|
54
|
+
const updatedFiles = [];
|
|
55
|
+
const fileStatusMap = stored.testFiles;
|
|
56
|
+
Object.entries(fileStatusMap).forEach(([filePath, status]) => {
|
|
57
|
+
if (status === true) {
|
|
58
|
+
updatedFiles.push(filePath);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return updatedFiles;
|
|
62
|
+
}
|
|
63
|
+
function generateUpdatedFilesSteps(stored, updatedFiles) {
|
|
64
|
+
const filesToRun = updatedFiles.map(toAbs).filter(Boolean);
|
|
65
|
+
const { detectedLanguage, detectedTestingFramework } = stored;
|
|
66
|
+
const exampleCommand = getFrameworkTestCommand(detectedLanguage, detectedTestingFramework);
|
|
67
|
+
return [
|
|
68
|
+
`Run only the updated files with Percy:\n` +
|
|
69
|
+
`Example: ${exampleCommand} <file1> <file2> ...`,
|
|
70
|
+
`Updated files to run:\n${filesToRun.join("\n")}`,
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
function generateInstructionSteps(instruction) {
|
|
74
|
+
return [
|
|
75
|
+
`Use the provided test command with Percy:\n${instruction}`,
|
|
76
|
+
`If this command fails or is incorrect, fall back to the default approach below.`,
|
|
77
|
+
];
|
|
78
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ValidatedEnvironment } from "../common/device-validator.js";
|
|
2
|
+
import { BrowserStackConfig } from "../../../lib/types.js";
|
|
2
3
|
export declare function generateBrowserStackYMLInstructions(config: {
|
|
3
4
|
validatedEnvironments?: ValidatedEnvironment[];
|
|
4
5
|
platforms?: string[];
|
|
5
6
|
enablePercy?: boolean;
|
|
6
7
|
projectName: string;
|
|
7
|
-
}): string;
|
|
8
|
+
}, browserStackConfig: BrowserStackConfig): string;
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
import { getBrowserStackAuth } from "../../../lib/get-auth.js";
|
|
2
|
+
export function generateBrowserStackYMLInstructions(config, browserStackConfig) {
|
|
2
3
|
const enablePercy = config.enablePercy || false;
|
|
3
4
|
const projectName = config.projectName || "BrowserStack Automate Build";
|
|
5
|
+
// Get credentials from config
|
|
6
|
+
const authString = getBrowserStackAuth(browserStackConfig);
|
|
7
|
+
const [username, accessKey] = authString.split(":");
|
|
4
8
|
// Generate platform configurations using the utility function
|
|
5
9
|
const platformConfigs = generatePlatformConfigs(config);
|
|
6
|
-
const stepTitle = "Create a browserstack.yml file in the project root with your validated device configurations:";
|
|
10
|
+
const stepTitle = "Create a browserstack.yml file in the project root with your validated device configurations:If already exists, update it with the following content for devices and project details.";
|
|
7
11
|
const buildName = `${projectName}-Build`;
|
|
8
12
|
let ymlContent = `
|
|
9
13
|
# ======================
|
|
10
14
|
# BrowserStack Reporting
|
|
11
15
|
# ======================
|
|
12
16
|
|
|
17
|
+
userName: ${username}
|
|
18
|
+
accessKey: ${accessKey}
|
|
19
|
+
|
|
13
20
|
# TODO: Replace these sample values with your actual project details
|
|
14
21
|
projectName: ${projectName}
|
|
15
22
|
buildName: ${buildName}
|
|
@@ -2,7 +2,7 @@ import { ConfigMapping } from "../common/types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* ---------- PYTHON INSTRUCTIONS ----------
|
|
4
4
|
*/
|
|
5
|
-
export declare const pythonInstructions: (
|
|
5
|
+
export declare const pythonInstructions: () => {
|
|
6
6
|
setup: string;
|
|
7
7
|
run: string;
|
|
8
8
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ---------- PYTHON INSTRUCTIONS ----------
|
|
3
3
|
*/
|
|
4
|
-
export const pythonInstructions = (
|
|
4
|
+
export const pythonInstructions = () => {
|
|
5
5
|
const setup = `
|
|
6
6
|
---STEP---
|
|
7
7
|
|
|
@@ -9,20 +9,18 @@ Install the BrowserStack SDK:
|
|
|
9
9
|
\`\`\`bash
|
|
10
10
|
python3 -m pip install browserstack-sdk
|
|
11
11
|
\`\`\`
|
|
12
|
-
|
|
13
|
-
---STEP---
|
|
14
|
-
|
|
15
|
-
Setup the BrowserStack SDK with your credentials:
|
|
16
|
-
\`\`\`bash
|
|
17
|
-
browserstack-sdk setup --username "${username}" --key "${accessKey}"
|
|
18
|
-
\`\`\`
|
|
19
12
|
`;
|
|
20
13
|
const run = `
|
|
21
14
|
---STEP---
|
|
22
15
|
|
|
23
16
|
Run your tests on BrowserStack:
|
|
24
17
|
\`\`\`bash
|
|
25
|
-
browserstack-sdk
|
|
18
|
+
browserstack-sdk pytest -s tests/<example_test>.py
|
|
19
|
+
\`\`\`
|
|
20
|
+
|
|
21
|
+
Or run all tests in a directory:
|
|
22
|
+
\`\`\`bash
|
|
23
|
+
browserstack-sdk pytest <path-to-test-directory>
|
|
26
24
|
\`\`\`
|
|
27
25
|
`;
|
|
28
26
|
return { setup, run };
|
|
@@ -45,11 +45,21 @@ export async function runBstackSDKOnly(input, config, isPercyAutomate = false) {
|
|
|
45
45
|
content: sdkSetupCommand,
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
+
const frameworkInstructions = getInstructionsForProjectConfiguration(input.detectedBrowserAutomationFramework, input.detectedTestingFramework, input.detectedLanguage, username, accessKey);
|
|
49
|
+
if (frameworkInstructions) {
|
|
50
|
+
if (frameworkInstructions.setup) {
|
|
51
|
+
steps.push({
|
|
52
|
+
type: "instruction",
|
|
53
|
+
title: "Framework-Specific Setup",
|
|
54
|
+
content: frameworkInstructions.setup,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
48
58
|
const ymlInstructions = generateBrowserStackYMLInstructions({
|
|
49
59
|
validatedEnvironments,
|
|
50
60
|
enablePercy: false,
|
|
51
61
|
projectName: input.projectName,
|
|
52
|
-
});
|
|
62
|
+
}, config);
|
|
53
63
|
if (ymlInstructions) {
|
|
54
64
|
steps.push({
|
|
55
65
|
type: "instruction",
|
|
@@ -57,15 +67,7 @@ export async function runBstackSDKOnly(input, config, isPercyAutomate = false) {
|
|
|
57
67
|
content: ymlInstructions,
|
|
58
68
|
});
|
|
59
69
|
}
|
|
60
|
-
const frameworkInstructions = getInstructionsForProjectConfiguration(input.detectedBrowserAutomationFramework, input.detectedTestingFramework, input.detectedLanguage, username, accessKey);
|
|
61
70
|
if (frameworkInstructions) {
|
|
62
|
-
if (frameworkInstructions.setup) {
|
|
63
|
-
steps.push({
|
|
64
|
-
type: "instruction",
|
|
65
|
-
title: "Framework-Specific Setup",
|
|
66
|
-
content: frameworkInstructions.setup,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
71
|
if (frameworkInstructions.run && !isPercyAutomate) {
|
|
70
72
|
steps.push({
|
|
71
73
|
type: "instruction",
|
|
@@ -5,7 +5,7 @@ export declare const PERCY_SNAPSHOT_COMMANDS_DESCRIPTION = "Adds Percy snapshot
|
|
|
5
5
|
export declare const RUN_ON_BROWSERSTACK_DESCRIPTION = "Set up and run automated web-based tests on BrowserStack using the BrowserStack SDK. Use this tool for functional or integration test setup on BrowserStack only. For any visual testing or Percy integration, use the dedicated Percy setup tool. Example prompts: run this test on browserstack; set up this project for browserstack.";
|
|
6
6
|
export declare const SIMULATE_PERCY_CHANGE_DESCRIPTION = "Integrate Percy visual testing into new projects and demonstrate visual change detection through a step-by-step simulation. This tool handles initial Percy integration, setup, and creates a working demonstration for new users. Primary tool for prompts like: \"Integrate percy for this project\", \"Integrate percy in this project {project_name}\"";
|
|
7
7
|
export declare const PERCY_REPLACE_REGEX: RegExp;
|
|
8
|
-
export declare const PERCY_SNAPSHOT_INSTRUCTION = "\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
8
|
+
export declare const PERCY_SNAPSHOT_INSTRUCTION = "\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n";
|
|
9
9
|
export declare const PERCY_SIMULATE_INSTRUCTION = "\nMANDATORY: Aggressive, Accurate Percy Snapshots Integration\n\nPrerequisite: Before making any code changes in the user's repository, create and switch to a new branch named browserstack-simulation. Stage all changes but do not commit them. If the repository has not been initialized yet, run git init first.\n\nYou MUST follow these steps with NO EXCEPTIONS:\n1. Identify 4-5 key test files in the project that are critical for visual testing.\n2. For EACH identified test file, analyze the code to find EVERY location where a Percy snapshot should be called (e.g., after each navigation, UI change, or significant state in tests).\n3. Insert snapshot calls at ALL such points, not just the first or most obvious one.\n\nIteratively update every selected test file with percy snapshot calls at all identified points, ensuring comprehensive coverage of visual changes.";
|
|
10
10
|
export declare const PERCY_SIMULATION_DRIVER_INSTRUCTION = "\nMANDATORY: Step-by-Step Percy Visual Change Simulation\nYou MUST follow these steps with NO EXCEPTIONS:\n\nSTEP 1: At this case we have added Percy snapshot commands to the test files at the appropriate locations (e.g., after navigation, UI change, or significant state). \n- Use ONLY existing snapshot names.\n- Do NOT add any popup injection or visual changes yet.\n- Do NOT run any Percy builds at this stage.\n\nSTEP 2: Run ONE comprehensive baseline Percy build that executes ALL tests containing Percy snapshots in a SINGLE build. This creates one baseline build with all snapshots for comparison. Use a command like: npx percy exec --label=mcp -- python -m pytest tests/ -k 'test_name1 or test_name2 or test_name3' -v to run multiple specific tests in one build.\"\n\nSTEP 3: Modify your test to inject a visible UI change (such as a popup) IMMEDIATELY BEFORE an EXISTING snapshot command (e.g., before percy_snapshot(self.driver, \"screenshot name\")).\n- Do NOT add a new snapshot name for the popup.\n- The popup must appear in an existing snapshot, not a new one.\n- Add this popup code in some test files before the percy_snapshot command you've added, to display the visual changes.\n\n```Javascript\npopup_script = `\nvar popup = document.createElement('div');\npopup.id = 'percy-test-popup';\npopup.style.cssText = popup.style.cssText = `\n /* TODO: Add styles to make the popup large, centered, and visually noticeable.\n Suggested properties: position: fixed; top/left; transform; background; color; font-size; padding; z-index; animation, etc. */\n`;\npopup.innerHTML = 'PERCY TEST<br>VISUAL CHANGE<br>DETECTED!';\ndocument.body.appendChild(popup);\n`;\n\n# Insert this just before the EXISTING snapshot command:\ndriver.execute_script(popup_script)\npercy_snapshot(self.driver, \"Before Adding to Cart\") # (Do NOT change the snapshot name, keep existing one)\n```\n\nSTEP 4: Run a second Percy build with same label and same test command as the baseline.\n- The snapshot names must remain the same as in the baseline.\n- The visual change should now appear in the same snapshot as before.\n- Use the same build command you ran for the baseline.\n\nSTEP 5: Compare the two Percy builds to see the detected visual difference.\n\nSTEP 6: Now ask user if they want to expand percy for other testcases? If yes, call the \"expandPercyVisualTesting\" tool to enable complete coverage for the entire project.\n\nCONSTRAINTS:\n- Do NOT run any builds until explicitly instructed in the steps.\n- Do NOT add new snapshot names\u2014only use existing ones.\n- Do NOT add popup injection until the baseline is established.\n- Visual changes must appear in EXISTING snapshots, not new ones.\n\nVALIDATION CHECKPOINTS (before proceeding to the next step):\n- Are you adding only snapshot commands (not running builds)?\n- Are you reusing existing snapshot names (not creating new ones)?\n- Have you established the baseline first (before adding visual changes)\n\nCRITICAL: \nDo NOT run tests separately or create multiple builds during baseline establishment. The goal is to have exactly TWO builds total: (1) baseline build with all original snapshots, (2) modified build with the same tests but visual changes injected.\n";
|
|
11
11
|
export declare const PERCY_VERIFICATION_REGEX: RegExp;
|
|
@@ -6,7 +6,7 @@ export const RUN_ON_BROWSERSTACK_DESCRIPTION = "Set up and run automated web-bas
|
|
|
6
6
|
export const SIMULATE_PERCY_CHANGE_DESCRIPTION = `Integrate Percy visual testing into new projects and demonstrate visual change detection through a step-by-step simulation. This tool handles initial Percy integration, setup, and creates a working demonstration for new users. Primary tool for prompts like: "Integrate percy for this project", "Integrate percy in this project {project_name}"`;
|
|
7
7
|
export const PERCY_REPLACE_REGEX = /Invoke listTestFiles\(\) with the provided directories[\s\S]*?- DO NOT STOP until you add commands in all the files or you reach end of the files\./;
|
|
8
8
|
export const PERCY_SNAPSHOT_INSTRUCTION = `
|
|
9
|
-
Invoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
9
|
+
Invoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---
|
|
10
10
|
Process files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:
|
|
11
11
|
- Start with index 0
|
|
12
12
|
- Then index 1
|
|
@@ -167,6 +167,13 @@ export async function validateDevices(devices, framework) {
|
|
|
167
167
|
}
|
|
168
168
|
validatedEnvironments.push(validatedEnv);
|
|
169
169
|
}
|
|
170
|
+
if (framework === SDKSupportedBrowserAutomationFrameworkEnum.playwright) {
|
|
171
|
+
validatedEnvironments.forEach((env) => {
|
|
172
|
+
if (env.browser) {
|
|
173
|
+
env.browser = env.browser.toLowerCase();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
170
177
|
return validatedEnvironments;
|
|
171
178
|
}
|
|
172
179
|
// Optimized desktop validation using nested indexed maps for O(1) lookups
|
|
@@ -19,7 +19,8 @@ export declare const SetUpPercyParamsShape: {
|
|
|
19
19
|
detectedBrowserAutomationFramework: z.ZodNativeEnum<typeof SDKSupportedBrowserAutomationFrameworkEnum>;
|
|
20
20
|
detectedTestingFramework: z.ZodNativeEnum<typeof SDKSupportedTestingFrameworkEnum>;
|
|
21
21
|
integrationType: z.ZodNativeEnum<typeof PercyIntegrationTypeEnum>;
|
|
22
|
-
folderPaths: z.ZodArray<z.ZodString, "many"
|
|
22
|
+
folderPaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
23
|
+
filePaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
23
24
|
};
|
|
24
25
|
export declare const RunTestsOnBrowserStackParamsShape: {
|
|
25
26
|
projectName: z.ZodString;
|
|
@@ -38,21 +39,24 @@ export declare const SetUpPercySchema: z.ZodObject<{
|
|
|
38
39
|
detectedBrowserAutomationFramework: z.ZodNativeEnum<typeof SDKSupportedBrowserAutomationFrameworkEnum>;
|
|
39
40
|
detectedTestingFramework: z.ZodNativeEnum<typeof SDKSupportedTestingFrameworkEnum>;
|
|
40
41
|
integrationType: z.ZodNativeEnum<typeof PercyIntegrationTypeEnum>;
|
|
41
|
-
folderPaths: z.ZodArray<z.ZodString, "many"
|
|
42
|
+
folderPaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
43
|
+
filePaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
42
44
|
}, "strip", z.ZodTypeAny, {
|
|
43
45
|
projectName: string;
|
|
44
46
|
detectedLanguage: SDKSupportedLanguageEnum;
|
|
45
47
|
detectedBrowserAutomationFramework: SDKSupportedBrowserAutomationFrameworkEnum;
|
|
46
48
|
detectedTestingFramework: SDKSupportedTestingFrameworkEnum;
|
|
47
49
|
integrationType: PercyIntegrationTypeEnum;
|
|
48
|
-
folderPaths
|
|
50
|
+
folderPaths?: string[] | undefined;
|
|
51
|
+
filePaths?: string[] | undefined;
|
|
49
52
|
}, {
|
|
50
53
|
projectName: string;
|
|
51
54
|
detectedLanguage: SDKSupportedLanguageEnum;
|
|
52
55
|
detectedBrowserAutomationFramework: SDKSupportedBrowserAutomationFrameworkEnum;
|
|
53
56
|
detectedTestingFramework: SDKSupportedTestingFrameworkEnum;
|
|
54
57
|
integrationType: PercyIntegrationTypeEnum;
|
|
55
|
-
folderPaths
|
|
58
|
+
folderPaths?: string[] | undefined;
|
|
59
|
+
filePaths?: string[] | undefined;
|
|
56
60
|
}>;
|
|
57
61
|
export declare const RunTestsOnBrowserStackSchema: z.ZodObject<{
|
|
58
62
|
projectName: z.ZodString;
|
|
@@ -24,7 +24,12 @@ export const SetUpPercyParamsShape = {
|
|
|
24
24
|
.describe("Specify the Percy integration type: web (Percy Web) or automate (Percy Automate). If not provided, always prompt the user with: 'Please specify the Percy integration type.' Do not proceed without an explicit selection. Never use a default."),
|
|
25
25
|
folderPaths: z
|
|
26
26
|
.array(z.string())
|
|
27
|
+
.optional()
|
|
27
28
|
.describe("An array of absolute folder paths containing UI test files. If not provided, analyze codebase for UI test folders by scanning for test patterns which contain UI test cases as per framework. Return empty array if none found."),
|
|
29
|
+
filePaths: z
|
|
30
|
+
.array(z.string())
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("An array of absolute file paths to specific UI test files. Use this when you want to target specific test files rather than entire folders. If not provided, will use folderPaths instead."),
|
|
28
33
|
};
|
|
29
34
|
export const RunTestsOnBrowserStackParamsShape = {
|
|
30
35
|
projectName: z
|
|
@@ -18,8 +18,8 @@ export declare function getPercyAutomateNotImplementedMessage(type: PercyAutomat
|
|
|
18
18
|
export declare function getBootstrapFailedMessage(error: unknown, context: {
|
|
19
19
|
config: unknown;
|
|
20
20
|
percyMode?: string;
|
|
21
|
-
sdkVersion?: string;
|
|
22
21
|
}): string;
|
|
23
22
|
export declare function percyUnsupportedResult(integrationType: PercyIntegrationTypeEnum, supportCheck?: {
|
|
24
23
|
errorMessage?: string;
|
|
25
24
|
}): CallToolResult;
|
|
25
|
+
export declare function validatePercyPathandFolders(input: any): void;
|
|
@@ -4,6 +4,7 @@ import { isPercyWebFrameworkSupported } from "../percy-web/frameworks.js";
|
|
|
4
4
|
import { formatInstructionsWithNumbers, generateVerificationMessage, } from "./formatUtils.js";
|
|
5
5
|
import { PercyAutomateNotImplementedType, } from "./types.js";
|
|
6
6
|
import { IMPORTANT_SETUP_WARNING } from "./index.js";
|
|
7
|
+
import { PackageJsonVersion } from "../../../index.js";
|
|
7
8
|
export function checkPercyIntegrationSupport(input) {
|
|
8
9
|
if (input.integrationType === PercyIntegrationTypeEnum.AUTOMATE) {
|
|
9
10
|
const isSupported = isPercyAutomateFrameworkSupported(input.detectedLanguage, input.detectedBrowserAutomationFramework || "", input.detectedTestingFramework || "");
|
|
@@ -73,7 +74,7 @@ export function getBootstrapFailedMessage(error, context) {
|
|
|
73
74
|
return `Failed to bootstrap project with BrowserStack SDK.
|
|
74
75
|
Error: ${error_message}
|
|
75
76
|
Percy Mode: ${context.percyMode ?? "automate"}
|
|
76
|
-
|
|
77
|
+
MCP Version: ${PackageJsonVersion}
|
|
77
78
|
Please open an issue on GitHub if the problem persists.`;
|
|
78
79
|
}
|
|
79
80
|
export function percyUnsupportedResult(integrationType, supportCheck) {
|
|
@@ -89,3 +90,13 @@ export function percyUnsupportedResult(integrationType, supportCheck) {
|
|
|
89
90
|
shouldSkipFormatting: true,
|
|
90
91
|
};
|
|
91
92
|
}
|
|
93
|
+
export function validatePercyPathandFolders(input) {
|
|
94
|
+
const hasFolderPaths = input.folderPaths && input.folderPaths.length > 0;
|
|
95
|
+
const hasFilePaths = input.filePaths && input.filePaths.length > 0;
|
|
96
|
+
if (!hasFolderPaths && !hasFilePaths) {
|
|
97
|
+
throw new Error("Please provide either:\n" +
|
|
98
|
+
"• folderPaths: Array of directory paths containing test files\n" +
|
|
99
|
+
"• filePaths: Array of specific test file paths\n\n" +
|
|
100
|
+
"Example: { filePaths: ['/path/to/test.spec.js'] }");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -6,8 +6,9 @@ import { runPercyWeb } from "./percy-web/handler.js";
|
|
|
6
6
|
import { runPercyAutomateOnly } from "./percy-automate/handler.js";
|
|
7
7
|
import { runBstackSDKOnly } from "./bstack/sdkHandler.js";
|
|
8
8
|
import { runPercyWithBrowserstackSDK } from "./percy-bstack/handler.js";
|
|
9
|
-
import { checkPercyIntegrationSupport } from "./common/utils.js";
|
|
9
|
+
import { checkPercyIntegrationSupport, validatePercyPathandFolders, } from "./common/utils.js";
|
|
10
10
|
import { SetUpPercySchema, RunTestsOnBrowserStackSchema, } from "./common/schema.js";
|
|
11
|
+
import { storedPercyResults } from "../../lib/inmemory-store.js";
|
|
11
12
|
import { getBootstrapFailedMessage, percyUnsupportedResult, } from "./common/utils.js";
|
|
12
13
|
import { PERCY_SIMULATE_INSTRUCTION, PERCY_REPLACE_REGEX, PERCY_SIMULATION_DRIVER_INSTRUCTION, PERCY_VERIFICATION_REGEX, } from "./common/constants.js";
|
|
13
14
|
export async function runTestsOnBrowserStackHandler(rawInput, config) {
|
|
@@ -18,14 +19,30 @@ export async function runTestsOnBrowserStackHandler(rawInput, config) {
|
|
|
18
19
|
export async function setUpPercyHandler(rawInput, config) {
|
|
19
20
|
try {
|
|
20
21
|
const input = SetUpPercySchema.parse(rawInput);
|
|
22
|
+
validatePercyPathandFolders(input);
|
|
23
|
+
// Clear any previous Percy results for a fresh start
|
|
24
|
+
storedPercyResults.clear();
|
|
25
|
+
storedPercyResults.set({
|
|
26
|
+
projectName: input.projectName,
|
|
27
|
+
detectedLanguage: input.detectedLanguage,
|
|
28
|
+
detectedBrowserAutomationFramework: input.detectedBrowserAutomationFramework,
|
|
29
|
+
detectedTestingFramework: input.detectedTestingFramework,
|
|
30
|
+
integrationType: input.integrationType,
|
|
31
|
+
folderPaths: input.folderPaths || [],
|
|
32
|
+
filePaths: input.filePaths || [],
|
|
33
|
+
testFiles: {},
|
|
34
|
+
});
|
|
21
35
|
const authorization = getBrowserStackAuth(config);
|
|
36
|
+
const folderPaths = input.folderPaths || [];
|
|
37
|
+
const filePaths = input.filePaths || [];
|
|
22
38
|
const percyInput = {
|
|
23
39
|
projectName: input.projectName,
|
|
24
40
|
detectedLanguage: input.detectedLanguage,
|
|
25
41
|
detectedBrowserAutomationFramework: input.detectedBrowserAutomationFramework,
|
|
26
42
|
detectedTestingFramework: input.detectedTestingFramework,
|
|
27
43
|
integrationType: input.integrationType,
|
|
28
|
-
folderPaths
|
|
44
|
+
folderPaths,
|
|
45
|
+
filePaths,
|
|
29
46
|
};
|
|
30
47
|
// Check for Percy Web integration support
|
|
31
48
|
if (input.integrationType === PercyIntegrationTypeEnum.WEB) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export declare const percyAutomateReviewSnapshotsStep = "\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n";
|
|
2
|
-
export declare const pythonPytestSeleniumInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Python SDK for Automate:\n pip install percy-selenium\n\n---STEP---\nUpdate your Pytest test script \n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
3
|
-
export declare const pythonPytestPlaywrightInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save @percy/cli\n - Install Percy Playwright SDK for Automate:\n pip install percy-playwright\n\n---STEP---\nUpdate your Playwright test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
4
|
-
export declare const jsCypressPercyAutomateInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Cypress SDK:\n npm install --save-dev @percy/cypress\n\n---STEP---\nUpdate your Cypress test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
2
|
+
export declare const pythonPytestSeleniumInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Python SDK for Automate:\n pip install percy-selenium\n\n---STEP---\nUpdate your Pytest test script \n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n - Import the Percy snapshot helper:\n from percy import percy_screenshot\n - In your test, take snapshots at key points:\n percy_screenshot(driver, \"Your snapshot name\")\n\nExample:\n```python\nimport pytest\nfrom selenium import webdriver\nfrom percy import percy_screenshot\n\n@pytest.fixture\ndef driver():\n driver = webdriver.Chrome()\n yield driver\n driver.quit()\n\ndef test_homepage(driver):\n driver.get(\"http://localhost:8000\")\n percy_screenshot(driver, \"Home page\")\n # ... more test steps ...\n percy_screenshot(driver, \"After login\")\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- browserstack-sdk pytest').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
3
|
+
export declare const pythonPytestPlaywrightInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save @percy/cli\n - Install Percy Playwright SDK for Automate:\n pip install percy-playwright\n\n---STEP---\nUpdate your Playwright test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n - Import the Percy screenshot helper:\n from percy import percy_screenshot\n - In your test, take snapshots at key points:\n percy_screenshot(page, name=\"Your snapshot name\")\n # You can pass `options`:\n percy_screenshot(page, name=\"Your snapshot name\", options={ \"full_page\": True })\n\nExample:\n```python\nfrom playwright.sync_api import sync_playwright\nfrom percy import percy_screenshot\n\ndef test_visual_regression():\n with sync_playwright() as p:\n browser = p.chromium.launch()\n page = browser.new_page()\n page.goto(\"http://localhost:8000\")\n percy_screenshot(page, name=\"Home page\")\n # ... more test steps ...\n percy_screenshot(page, name=\"After login\", options={ \"full_page\": True })\n browser.close()\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- <command to run the script file>').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
4
|
+
export declare const jsCypressPercyAutomateInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Cypress SDK:\n npm install --save-dev @percy/cypress\n\n---STEP---\nUpdate your Cypress test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n - Import and initialize Percy in your cypress/support/index.js:\n import '@percy/cypress';\n - In your test, take snapshots at key points:\n cy.percySnapshot('Your snapshot name');\n\nExample:\n```javascript\ndescribe('Percy Automate Cypress Example', () => {\n it('should take Percy snapshots', () => {\n cy.visit('http://localhost:8000');\n cy.percySnapshot('Home page');\n // ... more test steps ...\n cy.percySnapshot('After login');\n });\n});\n``` \n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- cypress run').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
5
5
|
export declare const mochaPercyAutomateInstructions = "\nInstall Percy Automate dependencies\n - Install Percy CLI:\n npm install --save @percy/cli\n - Install Percy Selenium SDK:\n npm install @percy/selenium-webdriver@2.0.1\n\n---STEP---\nUpdate your Mocha Automate test script\n - Import the Percy screenshot helper:\n const { percyScreenshot } = require('@percy/selenium-webdriver');\n - Use the Percy screenshot command to take required screenshots in your Automate session:\n await percyScreenshot(driver, 'Screenshot 1');\n options = { percyCSS: 'h1{color:red;}' };\n await percyScreenshot(driver, 'Screenshot 2', options);\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- mocha').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
6
6
|
export declare const mochaPercyPlaywrightInstructions = "\nInstall Percy Automate dependencies\n - Install the latest Percy CLI:\n npm install --save @percy/cli\n - Install the Percy Playwright SDK:\n npm install @percy/playwright\n\n---STEP---\nUpdate your Mocha Playwright test script\n - Import the Percy screenshot helper:\n const { percyScreenshot } = require(\"@percy/playwright\");\n - Use the Percy screenshot command to take required screenshots in your Automate session.\n\nExample:\n```javascript\nconst { percyScreenshot } = require(\"@percy/playwright\");\nawait percyScreenshot(page, \"Screenshot 1\");\n// With options\nawait percyScreenshot(page, \"Screenshot 2\", { percyCSS: \"h1{color:green;}\" });\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- <command to run the tests>').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
7
7
|
export declare const jestPercyAutomateInstructions = "\nInstall or upgrade the BrowserStack SDK:\n - Install the SDK:\n npm i -D browserstack-node-sdk@latest\n - Run the setup:\n npx setup --username \"YOUR_USERNAME\" --key \"YOUR_ACCESS_KEY\"\n\n---STEP---\nManually capture screenshots:\n 1. Import the BrowserStack Percy SDK in your test script:\n const { percy } = require('browserstack-node-sdk');\n 2. Use `percy.screenshot(driver, name)` at desired points in your test.\n\nExample:\n```javascript\nconst { percy } = require('browserstack-node-sdk');\ndescribe(\"JestJS test\", () => {\n let driver;\n const caps = require(\"../\" + conf_file).capabilities;\n\n beforeAll(() => {\n driver = new Builder()\n .usingServer(\"http://example-servername/hub\")\n .withCapabilities(caps)\n .build();\n });\n\n test(\"my test\", async () => {\n // ...\n await percy.screenshot(driver, \"My Screenshot\");\n // ...\n });\n});\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npm run [your-test-script-name]-browserstack').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
8
8
|
export declare const webdriverioPercyAutomateInstructions = "\nInstall or upgrade BrowserStack SDK\n - Install the BrowserStack SDK:\n npm i -D @wdio/browserstack-service\n\n---STEP---\nUpdate your WebdriverIO config file\n 1. Set `percy: true`\n 2. Set a `projectName`\n 3. Set `percyCaptureMode: auto` (or another mode as needed)\n\nExample WebdriverIO config:\n```js\nexports.config = {\n user: process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME',\n key: process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',\n hostname: 'hub.browserstack.com',\n services: [\n [\n 'browserstack',\n { browserstackLocal: true, opts: { forcelocal: false }, percy: true, percyCaptureMode: 'auto' }\n ],\n ],\n // add path to the test file\n}\n```\n\n---STEP---\n(Optional) Manually capture screenshots\n 1. Import the BrowserStack Percy SDK in your test script:\n const { percy } = require('browserstack-node-sdk');\n 2. Add the `await percy.screenshot(driver, name)` method at required points in your test script.\n\nExample:\n```javascript\n const { percy } = require('browserstack-node-sdk');\n 2. Add the `await percy.screenshot(driver, name)` method at required points in your test script.\n\nExample:\n```javascript\nconst { percy } = require('browserstack-node-sdk');\ndescribe(\"WebdriverIO Test\", () => {\n it(\"my test\", async () => {\n // ....\n await percy.screenshot(driver, \"My Screenshot\")\n // ....\n });\n});\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command as defined in your package.json file.\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
9
|
-
export declare const testcafePercyAutomateInstructions = "\nInstall Percy dependencies\n - Install the required dependencies:\n npm install --save-dev @percy/cli @percy/testcafe\n\n---STEP---\nUpdate your test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
9
|
+
export declare const testcafePercyAutomateInstructions = "\nInstall Percy dependencies\n - Install the required dependencies:\n npm install --save-dev @percy/cli @percy/testcafe\n\n---STEP---\nUpdate your test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n - Import the Percy library and use the percySnapshot function to take screenshots.\n\nExample:\n```javascript\nimport percySnapshot from '@percy/testcafe';\nfixture('MyFixture')\n .page('https://devexpress.github.io/testcafe/example/');\ntest('Test1', async t => {\n await t.typeText('#developer-name', 'John Doe');\n await percySnapshot(t, 'TestCafe Example');\n});\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- testcafe chrome:headless tests').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
10
10
|
export declare const javaPlaywrightJunitInstructions = "\nInstall Percy Automate dependencies\n - Install the latest Percy CLI:\n npm install --save @percy/cli\n - Add the Percy Playwright Java SDK to your pom.xml:\n```xml\n<dependency>\n <groupId>io.percy</groupId>\n <artifactId>percy-playwright-java</artifactId>\n <version>1.0.0</version>\n</dependency>\n```\n\n---STEP---\nUpdate your Automate test script\n - Import the Percy library:\n import io.percy.playwright.Percy;\n - Use the Percy screenshot command to take required screenshots in your Automate session.\n\nExample:\n```java\nPercy percy = new Percy(page);\npercy.screenshot(\"screenshot_1\");\n// With options\npercy.screenshot(\"screenshot_2\", options);\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- <command to run the automate script file>').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
11
11
|
export declare const csharpPlaywrightNunitInstructions = "\nInstall Percy Automate dependencies\n - Install the latest Percy CLI:\n npm install --save @percy/cli\n - Add the Percy Playwright SDK to your .csproj file:\n```xml\n<PackageReference Include=\"PercyIO.Playwright\" Version=\"1.0.0\" />\n```\n\n---STEP---\nUpdate your NUnit Playwright test script\n - Import the Percy library:\n using PercyIO.Playwright;\n - Use the Percy screenshot command to take required screenshots in your Automate session.\n\nExample:\n```csharp\nusing PercyIO.Playwright;\nPercy.Screenshot(page, \"example_screenshot_1\");\n// With options\nPercy.Screenshot(page, \"example_screenshot_2\", options);\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- <command to run the automate script file>').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const javaSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
2
|
-
export declare const nodejsSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
3
|
-
export declare const webdriverioPercyInstructions = "\nEnable Percy in `wdio.conf.js`:\nIn your WebdriverIO configuration file, modify the 'browserstack' service options to enable Percy.\n\n- Set `percy: true`.\n- Set a `projectName`. This is required and will be used for both your Automate and Percy projects.\n- Set `percyCaptureMode`. The default `manual` as we are adding screenshot commands manually.\n\nHere's how to modify the service configuration:\n```javascript\n// in wdio.conf.js\n\nexports.config = {\n // ... other configs\n services: [\n [\n 'browserstack',\n { \n // ... other service options\n percy: true,\n percyCaptureMode: 'manual' // or 'auto', etc.\n },\n ],\n ],\n\n commonCapabilities: {\n 'bstack:options': {\n projectName: \"My Percy Project\", // This is required for Percy\n // ... other common capabilities\n }\n },\n // ... rest of your config\n};\n```\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
4
|
-
export declare const csharpSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
1
|
+
export declare const javaSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\nAdd screenshot capture method at required points:\nUse the `PercySDK.screenshot(driver, name)` method at points in your test script where you want to capture screenshots.\n\nHere's an example:\n\n```java\n// ...imports\nimport com.browserstack.PercySDK;\n\npublic class YourTestClass extends YourBaseTest {\n @Test\n public void test() throws Exception {\n // your test logic\n // ...\n \n // Capture a Percy screenshot\n PercySDK.screenshot(driver, \"My Screenshot Name\");\n \n // ...\n // more test logic\n }\n}\n```\n";
|
|
2
|
+
export declare const nodejsSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n---STEP---\n\nAdd screenshot capture method at required points:\nUse the `percy.snapshot(driver, name)` method at points in your test script where you want to capture screenshots.\n\n```javascript\nconst { percy } = require('browserstack-node-sdk');\ndescribe(\"sample Test\", () => {\n // ... other imports and setup\n \n test(\"my test\", async () => {\n // ....\n await percy.screenshot(driver, \"My Snapshot\")\n // ....\n });\n})\n```\n";
|
|
3
|
+
export declare const webdriverioPercyInstructions = "\nEnable Percy in `wdio.conf.js`:\nIn your WebdriverIO configuration file, modify the 'browserstack' service options to enable Percy.\n\n- Set `percy: true`.\n- Set a `projectName`. This is required and will be used for both your Automate and Percy projects.\n- Set `percyCaptureMode`. The default `manual` as we are adding screenshot commands manually.\n\nHere's how to modify the service configuration:\n```javascript\n// in wdio.conf.js\n\nexports.config = {\n // ... other configs\n services: [\n [\n 'browserstack',\n { \n // ... other service options\n percy: true,\n percyCaptureMode: 'manual' // or 'auto', etc.\n },\n ],\n ],\n\n commonCapabilities: {\n 'bstack:options': {\n projectName: \"My Percy Project\", // This is required for Percy\n // ... other common capabilities\n }\n },\n // ... rest of your config\n};\n```\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n---STEP---\n\nManually Capturing Screenshots (Optional):\nIf you set `percyCaptureMode: 'manual'` or want to take extra screenshots in `auto` mode, you need to add screenshot commands to your tests.\n\nFirst, install `browserstack-node-sdk`:\n```bash\nnpm install browserstack-node-sdk\n```\n\nThen, in your test script, import `percy` and use it to take a snapshot:\n```javascript\n// your_test_file.js\nconst { percy } = require('browserstack-node-sdk');\n\ndescribe(\"My WebdriverIO Test\", () => {\n it(\"should take a percy snapshot\", async () => {\n // ... your test logic (e.g., browser.url('https://example.com'))\n \n // Capture a Percy screenshot\n await percy.screenshot(driver, \"My Snapshot Name\");\n \n // ... more test logic\n });\n});\n```\n";
|
|
4
|
+
export declare const csharpSeleniumInstructions = "\nImport the BrowserStack Percy SDK in your test script:\nAdd the Percy import to your test file.\n\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\nAdd screenshot capture method at required points:\nUse the `PercySDK.Screenshot(driver, name)` method at points in your test script where you want to capture screenshots.\n\nHere's an example:\n\n```csharp\nusing BrowserStackSDK.Percy;\nnamespace Tests;\n\npublic class MyTest\n{\n [Test]\n public void SampleTest()\n {\n // your test logic\n // ...\n \n // Capture a Percy screenshot\n PercySDK.Screenshot(driver, \"Screenshot name\");\n \n // ...\n // more test logic\n }\n}\n```\n";
|
|
@@ -67,7 +67,7 @@ export function runPercyWithBrowserstackSDK(input, config) {
|
|
|
67
67
|
platforms: input.devices?.map((t) => t.join(" ")) || [],
|
|
68
68
|
enablePercy: true,
|
|
69
69
|
projectName: input.projectName,
|
|
70
|
-
});
|
|
70
|
+
}, config);
|
|
71
71
|
if (ymlInstructions) {
|
|
72
72
|
steps.push({
|
|
73
73
|
type: "instruction",
|
|
@@ -19,23 +19,25 @@ export declare const nodejsGatsbyInstructionsSnapshot = "\n - Add the Percy plu
|
|
|
19
19
|
export declare const nodejsStorybookInstructionsSnapshot = "\n - Add Percy parameters to your stories to customize snapshots:\n```js\nMyStory.parameters = {\n percy: {\n name: 'My snapshot',\n additionalSnapshots: [\n { prefix: '[Dark mode] ', args: { colorScheme: 'dark' } },\n { suffix: ' with globals', globals: { textDirection: 'rtl' } },\n { name: 'Search snapshot', queryParams: { search: 'foobar' } }\n ]\n }\n};\n```\n - Use argument names and values defined in your codebase.\n";
|
|
20
20
|
export declare const pythonPlaywrightInstructionsSnapshot = "\n - Import the Percy snapshot helper and use the snapshot method:\n percy_snapshot(page, name=\"Your snapshot name\")\n - You can also use:\n percy_screenshot(page, name=\"Your snapshot name\", options={})\n\nExample:\n```python\nfrom playwright.sync_api import sync_playwright\nfrom percy import percy_snapshot\n\nwith sync_playwright() as p:\n browser = p.chromium.launch()\n page = browser.new_page()\n page.goto(\"http://localhost:8000\")\n percy_snapshot(page, name=\"Home page\")\n\n # ... more test steps ...\n percy_snapshot(page, name=\"After login\")\n\n browser.close()\n```\n";
|
|
21
21
|
export declare const csharpPlaywrightInstructionsSnapshot = "\n - Import the Percy snapshot helper and use the snapshot method:\n Percy.Snapshot(page, \"Your snapshot name\");\n - You can also pass options:\n Percy.Snapshot(page, \"Your snapshot name\", options);\n\nExample:\n```csharp\nusing Microsoft.Playwright;\nusing PercyIO.Playwright;\n\nclass PercyPlaywrightExample\n{\n public static async Task Main()\n {\n using var playwright = await Playwright.CreateAsync();\n var browser = await playwright.Chromium.LaunchAsync();\n var page = await browser.NewPageAsync();\n\n await page.GotoAsync(\"http://localhost:8000\");\n Percy.Snapshot(page, \"Home page\");\n\n // ... more test steps ...\n Percy.Snapshot(page, \"After login\");\n\n await browser.CloseAsync();\n }\n}\n```\n";
|
|
22
|
-
export declare const pythonInstructions = "\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Selenium Python package:\n pip install percy-selenium\nIf faced any issue create a virtual environment and proceed.\nUpdate your Python Selenium script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
23
|
-
export declare const nodejsInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy SDK for Node.js:\n npm install @percy/selenium-webdriver\n---STEP---\nUpdate your Node.js Selenium script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
24
|
-
export declare const javaInstructions = "\n---STEP---\nAdd Percy dependencies to your project\n - For Maven, add to your pom.xml:\n <dependency>\n <groupId>io.percy</groupId>\n <artifactId>percy-java-selenium</artifactId>\n <version>1.0.0</version>\n </dependency>\n - For Gradle, add to your build.gradle:\n implementation 'io.percy:percy-java-selenium:1.0.0'\n - For CLI usage, install Percy CLI:\n npm install --save-dev @percy/cli\n\n---STEP---\nUpdate your Java Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
25
|
-
export declare const rubyInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Ruby Selenium gem:\n gem install percy-selenium\n\n---STEP---\nUpdate your Ruby Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
26
|
-
export declare const rubyCapybaraInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Capybara gem:\n gem install percy-capybara\n\n---STEP---\nUpdate your Capybara or Rails test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
27
|
-
export declare const csharpInstructions = "\nInstall Percy CLI by running the following command:\nnpm install --save-dev @percy/cli\n\n---STEP---\nAdd Percy dependencies to your project\n - Add the Percy .NET Selenium NuGet package:\n dotnet add package PercyIO.Selenium\n\n---STEP---\nUpdate your C# Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
28
|
-
export declare const javaPlaywrightInstructions = "\nInstall Percy dependencies\n - For Maven, add to your pom.xml:\n <dependency>\n <groupId>io.percy</groupId>\n <artifactId>percy-playwright-java</artifactId>\n <version>1.0.0</version>\n </dependency>\n\n---STEP---\nUpdate your Java Playwright test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
29
|
-
export declare const nodejsPlaywrightInstructions = "\nInstall Percy dependencies\n - Install Percy Playwright SDK:\n npm install @percy/playwright\n\n---STEP---\nUpdate your Playwright JavaScript test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
30
|
-
export declare const nodejsWebdriverioInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Selenium Webdriver package:\n npm install --save-dev @percy/selenium-webdriver\n\n---STEP---\nUpdate your WebdriverIO test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
31
|
-
export declare const nodejsEmberInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Ember SDK:\n npm install --save-dev @percy/cli @percy/ember\n\n---STEP---\nUpdate your Ember test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
32
|
-
export declare const nodejsCypressInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Cypress SDK:\n npm install --save-dev @percy/cli @percy/cypress\n\n---STEP---\nUpdate your Cypress test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
33
|
-
export declare const nodejsPuppeteerInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Puppeteer SDK:\n npm install --save-dev @percy/cli @percy/puppeteer\n\n---STEP---\nUpdate your Puppeteer test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
34
|
-
export declare const nodejsNightmareInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Nightmare SDK:\n npm install --save-dev @percy/cli @percy/nightmare\n\n---STEP---\nUpdate your Nightmare test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
35
|
-
export declare const nodejsNightwatchInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Nightwatch SDK:\n npm install --save-dev @percy/cli @percy/nightwatch\n\n---STEP---\nUpdate your Nightwatch configuration and test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
36
|
-
export declare const nodejsProtractorInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Protractor SDK:\n npm install --save-dev @percy/cli @percy/protractor\n\n---STEP---\nUpdate your Protractor test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
37
|
-
export declare const nodejsTestcafeInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and TestCafe SDK:\n npm install --save-dev @percy/cli @percy/testcafe\n\n---STEP---\nUpdate your TestCafe test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
38
|
-
export declare const nodejsGatsbyInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Gatsby plugin:\n npm install --save @percy/cli gatsby-plugin-percy\n\n---STEP---\nUpdate your Gatsby configuration\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
39
|
-
export declare const nodejsStorybookInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Storybook SDK:\n npm install --save-dev @percy/cli @percy/storybook\n\n---STEP---\nUpdate your Storybook stories\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
40
|
-
export declare const pythonPlaywrightInstructions = "\n---STEP---\nCreate a Percy project\n - Sign in to Percy and create a project of type \"Web\". Name the project and note the generated token.\n\n---STEP---\nSet the project token as an environment variable\n - On macOS/Linux:\n export PERCY_TOKEN=\"<your token here>\"\n - On Windows PowerShell:\n $env:PERCY_TOKEN=\"<your token here>\"\n - On Windows CMD:\n set PERCY_TOKEN=<your token here>\n\n---STEP---\nInstall Percy dependencies\n - Install Percy Playwright SDK:\n pip install percy-playwright\n\n---STEP---\nUpdate your Playwright Python test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
41
|
-
export declare const csharpPlaywrightInstructions = "\nInstall Percy dependencies\n - Add the Percy Playwright NuGet package:\n <PackageReference Include=\"PercyIO.Playwright\" Version=\"1.0.0\" />\n\n---STEP---\nUpdate your Playwright .NET test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory
|
|
22
|
+
export declare const pythonInstructions = "\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Selenium Python package:\n pip install percy-selenium\nIf faced any issue create a virtual environment and proceed.\nUpdate your Python Selenium script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\nExample:\n```python\n- Import the Percy snapshot helper:\nfrom selenium import webdriver\nfrom percy import percy_snapshot\n\ndriver = webdriver.Chrome()\ndriver.get('http://localhost:8000')\npercy_snapshot(driver, 'Home page')\n# ... more test steps ...\npercy_snapshot(driver, 'After login')\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- python tests.py').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
23
|
+
export declare const nodejsInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy SDK for Node.js:\n npm install @percy/selenium-webdriver\n---STEP---\nUpdate your Node.js Selenium script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n- Import the Percy snapshot helper:\n const { percySnapshot } = require('@percy/selenium-js');\n - In your test, take snapshots like this:\n await percySnapshot(driver, \"Your snapshot name\");\n\nExample:\n```javascript\nconst { Builder } = require('selenium-webdriver');\nconst percySnapshot = require('@percy/selenium-webdriver');\n\nconst driver = await new Builder().forBrowser('chrome').build();\nawait driver.get('http://localhost:8000');\nawait percySnapshot(driver, 'Home page');\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- node script.js').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
24
|
+
export declare const javaInstructions = "\n---STEP---\nAdd Percy dependencies to your project\n - For Maven, add to your pom.xml:\n <dependency>\n <groupId>io.percy</groupId>\n <artifactId>percy-java-selenium</artifactId>\n <version>1.0.0</version>\n </dependency>\n - For Gradle, add to your build.gradle:\n implementation 'io.percy:percy-java-selenium:1.0.0'\n - For CLI usage, install Percy CLI:\n npm install --save-dev @percy/cli\n\n---STEP---\nUpdate your Java Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n import io.percy.selenium.Percy;\n - In your test, take snapshots like this:\n Percy percy = new Percy(driver);\n percy.snapshot(\"Your snapshot name\");\n Example:\n```java\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.chrome.ChromeDriver;\nimport io.percy.selenium.Percy;\n\npublic class PercyExample {\n public static void main(String[] args) {\n WebDriver driver = new ChromeDriver();\n driver.get(\"http://localhost:8000\");\n Percy percy = new Percy(driver);\n percy.snapshot(\"Home page\");\n driver.quit();\n }\n}\n```\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- mvn test').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
25
|
+
export declare const rubyInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Ruby Selenium gem:\n gem install percy-selenium\n\n---STEP---\nUpdate your Ruby Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Require the Percy snapshot helper:\n require 'percy'\n - In your test, take snapshots like this:\n Percy.snapshot(page, 'Your snapshot name')\n\nExample:\n```ruby\nrequire 'selenium-webdriver'\nrequire 'percy'\n\ndriver = Selenium::WebDriver.for :chrome\ndriver.get('http://localhost:8000')\nPercy.snapshot(driver, 'Your snapshot name')\ndriver.quit\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- bundle exec rspec').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
26
|
+
export declare const rubyCapybaraInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Capybara gem:\n gem install percy-capybara\n\n---STEP---\nUpdate your Capybara or Rails test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - In your test setup file, require percy/capybara:\n require 'percy/capybara'\n - In your test, take snapshots like this:\n page.percy_snapshot('Capybara snapshot')\n\nExample:\n```ruby\nrequire 'percy/capybara'\n\ndescribe 'my feature', type: :feature do\n it 'renders the page' do\n visit 'https://example.com'\n page.percy_snapshot('Capybara snapshot')\n end\nend\n```\n\n - The snapshot method arguments are:\n page.percy_snapshot(name[, options])\n name - The snapshot name; must be unique to each snapshot; defaults to the test title\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- bundle exec rspec').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
27
|
+
export declare const csharpInstructions = "\nInstall Percy CLI by running the following command:\nnpm install --save-dev @percy/cli\n\n---STEP---\nAdd Percy dependencies to your project\n - Add the Percy .NET Selenium NuGet package:\n dotnet add package PercyIO.Selenium\n\n---STEP---\nUpdate your C# Selenium test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n using PercyIO.Selenium;\n - In your test, take snapshots like this:\n Percy.Snapshot(driver,\"Your snapshot name\");\n\nExample:\n```csharp\nusing OpenQA.Selenium;\nusing OpenQA.Selenium.Chrome;\nusing PercyIO.Selenium;\n\nclass PercyExample\n{\n static void Main()\n {\n IWebDriver driver = new ChromeDriver();\n driver.Navigate().GoToUrl(\"http://localhost:8000\");\n Percy.Snapshot(driver,\"Empty Todo State\");\n driver.Quit();\n }\n}\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- dotnet test').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
28
|
+
export declare const javaPlaywrightInstructions = "\nInstall Percy dependencies\n - For Maven, add to your pom.xml:\n <dependency>\n <groupId>io.percy</groupId>\n <artifactId>percy-playwright-java</artifactId>\n <version>1.0.0</version>\n </dependency>\n\n---STEP---\nUpdate your Java Playwright test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy library and use the snapshot method:\n percy.snapshot(\"snapshot_1\");\n - You can also pass options:\n Map<String, Object> options = new HashMap<>();\n options.put(\"testCase\", \"Should add product to cart\");\n percy.snapshot(\"snapshot_2\", options);\n\nExample:\n```java\nimport com.microsoft.playwright.*;\nimport io.percy.playwright.*;\n\npublic class PercyPlaywrightExample {\n public static void main(String[] args) {\n try (Playwright playwright = Playwright.create()) {\n Browser browser = playwright.chromium().launch();\n Page page = browser.newPage();\n Percy percy = new Percy(page);\n\n page.navigate(\"http://localhost:8000\");\n percy.snapshot(\"Home page\");\n\n // ... more test steps ...\n percy.snapshot(\"After login\");\n\n browser.close();\n }\n }\n}\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g. npx percy exec -- <command to run the test script file>).\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
29
|
+
export declare const nodejsPlaywrightInstructions = "\nInstall Percy dependencies\n - Install Percy Playwright SDK:\n npm install @percy/playwright\n\n---STEP---\nUpdate your Playwright JavaScript test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n const percySnapshot = require('@percy/playwright');\n - In your test, take snapshots like this:\n await percySnapshot(page, \"Your snapshot name\");\n\nExample:\n```javascript\nconst { chromium } = require('playwright');\nconst percySnapshot = require('@percy/playwright');\n\n(async () => {\n const browser = await chromium.launch();\n const page = await browser.newPage();\n await page.goto('http://example.com/', { waitUntil: 'networkidle' });\n await percySnapshot(page, 'Example Site');\n await browser.close();\n})();\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., npx percy exec -- <command to run the test script file>).\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
30
|
+
export declare const nodejsWebdriverioInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI:\n npm install --save-dev @percy/cli\n - Install Percy Selenium Webdriver package:\n npm install --save-dev @percy/selenium-webdriver\n\n---STEP---\nUpdate your WebdriverIO test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n const percySnapshot = require('@percy/selenium-webdriver');\n - In your test, take snapshots like this:\n await percySnapshot(driver, \"Your snapshot name\");\n\nExample:\n```javascript\nconst { remote } = require('webdriverio');\nconst percySnapshot = require('@percy/selenium-webdriver');\n\n(async () => {\n const browser = await remote({\n logLevel: 'error',\n capabilities: { browserName: 'chrome' }\n });\n\n await browser.url('https://example.com');\n await percySnapshot(browser, 'WebdriverIO example');\n await browser.deleteSession();\n})();\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- wdio run wdio.conf.js').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
31
|
+
export declare const nodejsEmberInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Ember SDK:\n npm install --save-dev @percy/cli @percy/ember\n\n---STEP---\nUpdate your Ember test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n import percySnapshot from '@percy/ember';\n - In your test, take snapshots like this:\n await percySnapshot('My Snapshot');\n\nExample:\n```javascript\nimport percySnapshot from '@percy/ember';\ndescribe('My ppp', () => {\n // ...app setup\n it('about page should look good', async () => {\n await visit('/about');\n await percySnapshot('My Snapshot');\n });\n});\n```\n\n - The snapshot method arguments are:\n percySnapshot(name[, options])\n name - The snapshot name; must be unique to each snapshot; defaults to the test title\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- ember test').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
32
|
+
export declare const nodejsCypressInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Cypress SDK:\n npm install --save-dev @percy/cli @percy/cypress\n\n---STEP---\nUpdate your Cypress test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper in your cypress/support/e2e.js file:\n import '@percy/cypress';\n - If you\u2019re using TypeScript, include \"types\": [\"cypress\", \"@percy/cypress\"] in your tsconfig.json file.\n - In your test, take snapshots like this:\n cy.percySnapshot();\n\nExample:\n```javascript\nimport '@percy/cypress';\n\ndescribe('Integration test with visual testing', function() {\n it('Loads the homepage', function() {\n // Load the page or perform any other interactions with the app.\n cy.visit('<URL under test>');\n // Take a snapshot for visual diffing\n cy.percySnapshot();\n });\n});\n```\n\n - The snapshot method arguments are:\n cy.percySnapshot([name][, options])\n name - The snapshot name; must be unique to each snapshot; defaults to the test title\n options - See per-snapshot configuration options\n\n - For example:\n cy.percySnapshot();\n cy.percySnapshot('Homepage test');\n cy.percySnapshot('Homepage responsive test', { widths: [768, 992, 1200] });\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- cypress run').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
33
|
+
export declare const nodejsPuppeteerInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Puppeteer SDK:\n npm install --save-dev @percy/cli @percy/puppeteer\n\n---STEP---\nUpdate your Puppeteer test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n const percySnapshot = require('@percy/puppeteer');\n - In your test, take snapshots like this:\n await percySnapshot(page, 'Snapshot name');\n\nExample:\n```javascript\nconst puppeteer = require('puppeteer');\nconst percySnapshot = require('@percy/puppeteer');\n\ndescribe('Integration test with visual testing', function() {\n it('Loads the homepage', async function() {\n const browser = await puppeteer.launch();\n const page = await browser.newPage();\n await page.goto('https://example.com');\n await percySnapshot(page, this.test.fullTitle());\n await browser.close();\n });\n});\n```\n\n - The snapshot method arguments are:\n percySnapshot(page, name[, options])\n page (required) - A puppeteer page instance\n name (required) - The snapshot name; must be unique to each snapshot\n options - See per-snapshot configuration options\n\n - For example:\n percySnapshot(page, 'Homepage test');\n percySnapshot(page, 'Homepage responsive test', { widths: [768, 992, 1200] });\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- <command to run the test script file>').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
34
|
+
export declare const nodejsNightmareInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Nightmare SDK:\n npm install --save-dev @percy/cli @percy/nightmare\n\n---STEP---\nUpdate your Nightmare test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n const Nightmare = require('nightmare');\n const percySnapshot = require('@percy/nightmare');\n - In your test, take snapshots like this:\n .use(percySnapshot('Snapshot name'))\n\nExample:\n```javascript\nconst Nightmare = require('nightmare');\nconst percySnapshot = require('@percy/nightmare');\n\nNightmare()\n .goto('http://example.com')\n // ... other actions ...\n .use(percySnapshot('Example Snapshot'))\n // ... more actions ...\n .end()\n .then(() => {\n // ...\n });\n```\n\n - The snapshot method arguments are:\n percySnapshot(name[, options])\n name (required) - The snapshot name; must be unique to each snapshot\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- node script.js').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
35
|
+
export declare const nodejsNightwatchInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Nightwatch SDK:\n npm install --save-dev @percy/cli @percy/nightwatch\n\n---STEP---\nUpdate your Nightwatch configuration and test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy library and add the path exported by @percy/nightwatch to your Nightwatch configuration\u2019s custom_commands_path property:\n const percy = require('@percy/nightwatch');\n module.exports = {\n // ...\n custom_commands_path: [percy.path],\n // ...\n };\n - In your test, take snapshots like this:\n browser.percySnapshot('Snapshot name');\n\nExample:\n```javascript\nconst percy = require('@percy/nightwatch');\nmodule.exports = {\n // ...\n custom_commands_path: [percy.path],\n // ...\n};\n\n// Example test\nmodule.exports = {\n 'Snapshots pages': function(browser) {\n browser\n .url('http://example.com')\n .assert.containsText('h1', 'Example Domain')\n .percySnapshot('Example snapshot');\n browser\n .url('http://google.com')\n .assert.elementPresent('img[alt=\"Google\"]')\n .percySnapshot('Google homepage');\n browser.end();\n }\n};\n```\n\n - The snapshot method arguments are:\n percySnapshot([name][, options])\n name (required) - The snapshot name; must be unique to each snapshot\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- nightwatch').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
36
|
+
export declare const nodejsProtractorInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Protractor SDK:\n npm install --save-dev @percy/cli @percy/protractor\n\n---STEP---\nUpdate your Protractor test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n import percySnapshot from '@percy/protractor';\n - In your test, take snapshots like this:\n await percySnapshot('Snapshot name');\n // or\n await percySnapshot(browser, 'Snapshot name');\n\nExample:\n```javascript\nimport percySnapshot from '@percy/protractor';\ndescribe('angularjs homepage', function() {\n it('should greet the named user', async function() {\n await browser.get('https://www.angularjs.org');\n await percySnapshot('AngularJS homepage');\n await element(by.model('yourName')).sendKeys('Percy');\n var greeting = element(by.binding('yourName'));\n expect(await greeting.getText()).toEqual('Hello Percy!');\n await percySnapshot('AngularJS homepage greeting');\n });\n});\n```\n\n - The snapshot method arguments are:\n percySnapshot(name[, options])\n Standalone mode:\n percySnapshot(browser, name[, options])\n browser (required) - The Protractor browser object\n name (required) - The snapshot name; must be unique to each snapshot\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- protractor conf.js').\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
37
|
+
export declare const nodejsTestcafeInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and TestCafe SDK:\n npm install --save-dev @percy/cli @percy/testcafe\n\n---STEP---\nUpdate your TestCafe test script\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper:\n import percySnapshot from '@percy/testcafe';\n - In your test, take snapshots like this:\n await percySnapshot(t, 'Snapshot name');\n\nExample:\n```javascript\nimport percySnapshot from '@percy/testcafe';\nfixture('MyFixture')\n .page('https://devexpress.github.io/testcafe/example');\ntest('Test1', async t => {\n await t.typeText('#developer-name', 'John Doe');\n await percySnapshot(t, 'TestCafe Example');\n});\n```\n\n - The snapshot method arguments are:\n percySnapshot(t, name[, options])\n t (required) - The test controller instance passed from test\n name (required) - The snapshot name; must be unique to each snapshot\n options - See per-snapshot configuration options\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- testcafe chrome:headless tests').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
38
|
+
export declare const nodejsGatsbyInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Gatsby plugin:\n npm install --save @percy/cli gatsby-plugin-percy\n\n---STEP---\nUpdate your Gatsby configuration\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Add the Percy plugin to your gatsby-config.js file:\n module.exports = {\n plugins: [`gatsby-plugin-percy`]\n }\n\n - The plugin will take snapshots of discovered pages during the build process.\n\n - Example gatsby-config.js with options:\n```javascript\nmodule.exports = {\n plugins: [{\n resolve: `gatsby-plugin-percy`,\n options: {\n // gatsby specific options\n query: `{\n allSitePage { nodes { path } }\n allOtherPage { nodes { path } }\n }`,\n resolvePages: ({\n allSitePage: { nodes: allPages },\n allOtherPage: { nodes: otherPages }\n }) => {\n return [...allPages, ...otherPages]\n .map(({ path }) => path);\n },\n // percy static snapshot options\n exclude: [\n '/dev-404-page/',\n '/offline-plugin-app-shell-fallback/'\n ],\n overrides: [{\n include: '/foobar/',\n waitForSelector: '.done-loading',\n additionalSnapshots: [{\n suffix: ' - after btn click',\n execute: () => document.querySelector('.btn').click()\n }]\n }]\n }\n }]\n}\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g., 'npx percy exec -- gatsby build').\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
39
|
+
export declare const nodejsStorybookInstructions = "\n---STEP---\nInstall Percy dependencies\n - Install Percy CLI and Storybook SDK:\n npm install --save-dev @percy/cli @percy/storybook\n\n---STEP---\nUpdate your Storybook stories\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Add Percy parameters to your stories to customize snapshots:\n```js\nMyStory.parameters = {\n percy: {\n name: 'My snapshot',\n additionalSnapshots: [\n { prefix: '[Dark mode] ', args: { colorScheme: 'dark' } },\n { suffix: ' with globals', globals: { textDirection: 'rtl' } },\n { name: 'Search snapshot', queryParams: { search: 'foobar' } }\n ]\n }\n};\n```\n - Use argument names and values defined in your codebase.\n\n\n---STEP---\nRun Percy with your Storybook\n - With a static Storybook build:\n percy storybook ./storybook-build\n - With a local or live Storybook URL:\n percy storybook http://localhost:9009\n percy storybook https://storybook.foobar.com\n - Automatically run start-storybook:\n Run this scan using tool runPercyScan with 'npx percy exec -- percy storybook:start --port=9009'.\n\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
40
|
+
export declare const pythonPlaywrightInstructions = "\n---STEP---\nCreate a Percy project\n - Sign in to Percy and create a project of type \"Web\". Name the project and note the generated token.\n\n---STEP---\nSet the project token as an environment variable\n - On macOS/Linux:\n export PERCY_TOKEN=\"<your token here>\"\n - On Windows PowerShell:\n $env:PERCY_TOKEN=\"<your token here>\"\n - On Windows CMD:\n set PERCY_TOKEN=<your token here>\n\n---STEP---\nInstall Percy dependencies\n - Install Percy Playwright SDK:\n pip install percy-playwright\n\n---STEP---\nUpdate your Playwright Python test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper and use the snapshot method:\n percy_snapshot(page, name=\"Your snapshot name\")\n - You can also use:\n percy_screenshot(page, name=\"Your snapshot name\", options={})\n\nExample:\n```python\nfrom playwright.sync_api import sync_playwright\nfrom percy import percy_snapshot\n\nwith sync_playwright() as p:\n browser = p.chromium.launch()\n page = browser.new_page()\n page.goto(\"http://localhost:8000\")\n percy_snapshot(page, name=\"Home page\")\n\n # ... more test steps ...\n percy_snapshot(page, name=\"After login\")\n\n browser.close()\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g. npx percy exec -- <command to run the test script file>).\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
41
|
+
export declare const csharpPlaywrightInstructions = "\nInstall Percy dependencies\n - Add the Percy Playwright NuGet package:\n <PackageReference Include=\"PercyIO.Playwright\" Version=\"1.0.0\" />\n\n---STEP---\nUpdate your Playwright .NET test\n\nInvoke listTestFiles() with the provided directories from user to gather all test files in memory ---STEP---\nProcess files in STRICT sequential order using tool addPercySnapshotCommands() with below instructions:\n- Start with index 0\n- Then index 1 \n- Then index 2\n- Continue sequentially until the last index\n- DO NOT skip any index numbers\n- DO NOT jump to random indices like 10, 20, 30\n- DO NOT worry about time consuming and any constraints.\n- DO NOT STOP until you add commands in all the files or you reach end of the files.\n\n\n - Import the Percy snapshot helper and use the snapshot method:\n Percy.Snapshot(page, \"Your snapshot name\");\n - You can also pass options:\n Percy.Snapshot(page, \"Your snapshot name\", options);\n\nExample:\n```csharp\nusing Microsoft.Playwright;\nusing PercyIO.Playwright;\n\nclass PercyPlaywrightExample\n{\n public static async Task Main()\n {\n using var playwright = await Playwright.CreateAsync();\n var browser = await playwright.Chromium.LaunchAsync();\n var page = await browser.NewPageAsync();\n\n await page.GotoAsync(\"http://localhost:8000\");\n Percy.Snapshot(page, \"Home page\");\n\n // ... more test steps ...\n Percy.Snapshot(page, \"After login\");\n\n await browser.CloseAsync();\n }\n}\n```\n\n\n---STEP---\nTo run the Percy build, call the tool runPercyScan with the appropriate test command (e.g. npx percy exec -- <command to run the test script file>).\n\n---STEP---\nReview the snapshots\n - Go to your Percy project on https://percy.io to review snapshots and approve/reject any visual changes.\n\n";
|
|
42
|
+
export declare function getFrameworkTestCommand(language: string, framework: string): string;
|
|
43
|
+
export declare const PERCY_FALLBACK_STEPS: string[];
|
|
@@ -881,3 +881,42 @@ ${csharpPlaywrightInstructionsSnapshot}
|
|
|
881
881
|
To run the Percy build, call the tool runPercyScan with the appropriate test command (e.g. npx percy exec -- <command to run the test script file>).
|
|
882
882
|
${percyReviewSnapshotsStep}
|
|
883
883
|
`;
|
|
884
|
+
export function getFrameworkTestCommand(language, framework) {
|
|
885
|
+
const percyPrefix = "npx percy exec --labels=mcp --";
|
|
886
|
+
const nodeCommands = {
|
|
887
|
+
cypress: "cypress run",
|
|
888
|
+
playwright: "playwright test",
|
|
889
|
+
webdriverio: "wdio",
|
|
890
|
+
puppeteer: "node",
|
|
891
|
+
testcafe: "testcafe",
|
|
892
|
+
nightwatch: "nightwatch",
|
|
893
|
+
protractor: "protractor",
|
|
894
|
+
gatsby: "gatsby build",
|
|
895
|
+
storybook: "storybook build",
|
|
896
|
+
ember: "ember test",
|
|
897
|
+
default: "npm test",
|
|
898
|
+
};
|
|
899
|
+
const languageMap = {
|
|
900
|
+
python: "python -m pytest",
|
|
901
|
+
java: "mvn test",
|
|
902
|
+
ruby: "bundle exec rspec",
|
|
903
|
+
csharp: "dotnet test",
|
|
904
|
+
};
|
|
905
|
+
if (language === "nodejs") {
|
|
906
|
+
const cmd = nodeCommands[framework] ?? nodeCommands.default;
|
|
907
|
+
return `${percyPrefix} ${cmd}`;
|
|
908
|
+
}
|
|
909
|
+
const cmd = languageMap[language];
|
|
910
|
+
return cmd ? `${percyPrefix} ${cmd}` : `${percyPrefix} <test-runner>`;
|
|
911
|
+
}
|
|
912
|
+
export const PERCY_FALLBACK_STEPS = [
|
|
913
|
+
`Attempt to infer the project's test command from context (high confidence commands first):
|
|
914
|
+
- Node.js: npm test, cypress run, npx playwright test, npx wdio, npx testcafe, npx nightwatch, npx protractor, ember test, npx gatsby build, npx storybook build
|
|
915
|
+
- Python: python -m pytest
|
|
916
|
+
- Java: mvn test
|
|
917
|
+
- Ruby: bundle exec rspec
|
|
918
|
+
- C#: dotnet test
|
|
919
|
+
or from package.json scripts`,
|
|
920
|
+
`Wrap the inferred command with Percy along with label: \nnpx percy exec --labels=mcp -- <test command>`,
|
|
921
|
+
`If the test command cannot be inferred confidently, ask the user directly for the correct test command.`,
|
|
922
|
+
];
|