Skip to content

Commit ff740fa

Browse files
committed
update instructions and error handling
1 parent e04745a commit ff740fa

File tree

4 files changed

+64
-53
lines changed

4 files changed

+64
-53
lines changed

src/tools/sdk-utils/common/constants.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Process files in STRICT sequential order using tool addPercySnapshotCommands() w
3535
export const PERCY_SIMULATE_INSTRUCTION = `
3636
MANDATORY: Aggressive, Accurate Percy Snapshots Integration
3737
38-
Prerequisite: Before making any code changes in the user's repo, switch to a branch named temp-percy (run git init first if the repo is not yet initialized).
38+
Prerequisite: 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.
3939
4040
You MUST follow these steps with NO EXCEPTIONS:
4141
1. Identify 4-5 key test files in the project that are critical for visual testing.
@@ -78,13 +78,13 @@ percy_snapshot(self.driver, "Before Adding to Cart") # (Do NOT change the snaps
7878
\`\`\`
7979
8080
STEP 4: Run a second Percy build.
81+
- Strictly use the same build command you ran for the baseline.
8182
- The snapshot names must remain the same as in the baseline.
8283
- The visual change should now appear in the same snapshot as before.
83-
- Use the same build command you ran for the baseline.
8484
8585
STEP 5: Compare the two Percy builds to see the detected visual difference.
8686
87-
STEP 6: Now ask user if they want to setup percy for full project coverage? If yes, call the "setupPercyVisualTesting" tool to enable complete coverage for the entire project.
87+
STEP 6: Now ask user if they want to setup percy for full project coverage? If yes, discard all the unstaged changes and call the "setupPercyVisualTesting" tool to enable complete coverage for the entire project.
8888
8989
CONSTRAINTS:
9090
- Do NOT run any builds until explicitly instructed in the steps.
@@ -100,3 +100,6 @@ VALIDATION CHECKPOINTS (before proceeding to the next step):
100100
CRITICAL:
101101
Do 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.
102102
`;
103+
104+
export const PERCY_VERIFICATION_REGEX =
105+
/\*\* Verification:\*\*\nPlease verify that you have completed all[\s\S]*?double-check each step and ensure all commands executed successfully\./s;

src/tools/sdk-utils/common/utils.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,12 @@ export function getBootstrapFailedMessage(
102102
error: unknown,
103103
context: { config: unknown; percyMode?: string; sdkVersion?: string },
104104
): string {
105+
const errorMsg = error instanceof Error ? error.message : String(error);
105106
return `Failed to bootstrap project with BrowserStack SDK.
106-
Error: ${error}
107-
Percy Mode: ${context.percyMode ?? "automate"}
108-
SDK Version: ${context.sdkVersion ?? "N/A"}
109-
Please open an issue on GitHub if the problem persists.`;
107+
Error: ${errorMsg}
108+
Percy Mode: ${context.percyMode ?? "N/A"}
109+
SDK Version: ${context.sdkVersion ?? "N/A"}
110+
Please open an issue on GitHub if the problem persists.`;
110111
}
111112

112113
export function percyUnsupportedResult(

src/tools/sdk-utils/handler.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
PERCY_SIMULATE_INSTRUCTION,
2222
PERCY_REPLACE_REGEX,
2323
PERCY_SIMULATION_DRIVER_INSTRUCTION,
24+
PERCY_VERIFICATION_REGEX,
2425
} from "./common/constants.js";
2526

2627
export async function runTestsOnBrowserStackHandler(
@@ -172,23 +173,27 @@ export async function setUpSimulatePercyChangeHandler(
172173
config: BrowserStackConfig,
173174
): Promise<CallToolResult> {
174175
try {
175-
const percyInstruction = await setUpPercyHandler(rawInput, config);
176+
let percyInstruction;
176177

178+
try {
179+
percyInstruction = await setUpPercyHandler(rawInput, config);
180+
} catch {
181+
throw new Error("Failed to set up Percy");
182+
}
183+
177184
if (percyInstruction.isError) {
178185
return percyInstruction;
179186
}
180187

181188
if (Array.isArray(percyInstruction.content)) {
182-
percyInstruction.content.forEach((item) => {
183-
if (
184-
typeof item.text === "string" &&
185-
PERCY_REPLACE_REGEX.test(item.text)
186-
) {
187-
item.text = item.text.replace(
188-
PERCY_REPLACE_REGEX,
189-
PERCY_SIMULATE_INSTRUCTION,
190-
);
189+
percyInstruction.content = percyInstruction.content.map((item) => {
190+
if (typeof item.text === "string") {
191+
let updatedText = item.text
192+
.replace(PERCY_REPLACE_REGEX, PERCY_SIMULATE_INSTRUCTION)
193+
.replace(PERCY_VERIFICATION_REGEX, "");
194+
return { ...item, text: updatedText };
191195
}
196+
return item;
192197
});
193198
}
194199

src/tools/sdk-utils/percy-web/fetchPercyToken.ts

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,43 @@ export async function fetchPercyToken(
55
authorization: string,
66
options: { type?: PercyIntegrationTypeEnum } = {},
77
): Promise<string> {
8-
try {
9-
const authHeader = `Basic ${Buffer.from(authorization).toString("base64")}`;
10-
const baseUrl =
11-
"https://api.browserstack.com/api/app_percy/get_project_token";
12-
const params = new URLSearchParams({ name: projectName });
13-
14-
if (options.type) {
15-
params.append("type", options.type);
16-
}
17-
18-
const url = `${baseUrl}?${params.toString()}`;
19-
20-
const response = await fetch(url, {
21-
headers: {
22-
Authorization: authHeader,
23-
},
24-
});
25-
26-
if (!response.ok) {
27-
throw new Error(
28-
`Failed to fetch Percy token (status: ${response.status})`,
29-
);
30-
}
31-
32-
const data = await response.json();
33-
34-
if (!data?.token || !data?.success) {
35-
throw new Error(
36-
"Project exists but is likely set up for Automate. Please use a different project name.",
37-
);
38-
}
39-
40-
return data.token;
41-
} catch (err) {
42-
const message = err instanceof Error ? err.message : "Unknown error";
43-
throw new Error(`Error retrieving Percy token: ${message}`);
8+
const authHeader = `Basic ${Buffer.from(authorization).toString("base64")}`;
9+
10+
const baseUrl =
11+
"https://api.browserstack.com/api/app_percy/get_project_token";
12+
const params = new URLSearchParams({ name: projectName });
13+
14+
if (!projectName) {
15+
throw new Error("Project name is required for setting up the Percy");
16+
}
17+
18+
if (options.type) {
19+
params.append("type", options.type);
20+
}
21+
22+
const url = `${baseUrl}?${params.toString()}`;
23+
24+
return "newtoken";
25+
26+
const response = await fetch(url, {
27+
headers: {
28+
Authorization: authHeader,
29+
},
30+
});
31+
32+
if (!response.ok) {
33+
throw new Error(
34+
`Failed to fetch Percy token (status: ${response.status})`,
35+
);
36+
}
37+
38+
const data = await response.json();
39+
40+
if (!data?.token || !data?.success) {
41+
throw new Error(
42+
"Project exists but is likely set up for Automate. Please use a different project name.",
43+
);
4444
}
45+
46+
return data.token;
4547
}

0 commit comments

Comments
 (0)