Skip to content

Commit 0c34386

Browse files
authored
Merge branch 'SDK_PERCY_1' into cont-regression
2 parents d3d5474 + 669f086 commit 0c34386

File tree

8 files changed

+575
-18
lines changed

8 files changed

+575
-18
lines changed

src/tools/bstack-sdk.ts

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,20 @@ import {
55
SDKSupportedBrowserAutomationFramework,
66
SDKSupportedLanguage,
77
SDKSupportedTestingFramework,
8+
SDKSupportedLanguageEnum,
9+
SDKSupportedBrowserAutomationFrameworkEnum,
10+
SDKSupportedTestingFrameworkEnum,
811
} from "./sdk-utils/types.js";
912
import {
1013
generateBrowserStackYMLInstructions,
1114
getInstructionsForProjectConfiguration,
1215
} from "./sdk-utils/instructions.js";
1316
import { trackMCP } from "../lib/instrumentation.js";
17+
import {
18+
formatPercyInstructions,
19+
getPercyInstructions,
20+
} from "./sdk-utils/percy/instructions.js";
21+
import { getSDKPrefixCommand } from "./sdk-utils/commands.js";
1422

1523
/**
1624
* BrowserStack SDK hooks into your test framework to seamlessly run tests on BrowserStack.
@@ -21,25 +29,79 @@ export async function bootstrapProjectWithSDK({
2129
detectedTestingFramework,
2230
detectedLanguage,
2331
desiredPlatforms,
32+
enablePercy,
2433
}: {
2534
detectedBrowserAutomationFramework: SDKSupportedBrowserAutomationFramework;
2635
detectedTestingFramework: SDKSupportedTestingFramework;
2736
detectedLanguage: SDKSupportedLanguage;
2837
desiredPlatforms: string[];
38+
enablePercy: boolean;
2939
}): Promise<CallToolResult> {
30-
const instructions = generateBrowserStackYMLInstructions(desiredPlatforms);
40+
// Handle frameworks with unique setup instructions that don't use browserstack.yml
41+
if (
42+
detectedBrowserAutomationFramework === "cypress" ||
43+
detectedTestingFramework === "webdriverio"
44+
) {
45+
let instructions = getInstructionsForProjectConfiguration(
46+
detectedBrowserAutomationFramework,
47+
detectedTestingFramework,
48+
detectedLanguage,
49+
);
50+
if (enablePercy) {
51+
const percyInstructions = getPercyInstructions(
52+
detectedLanguage,
53+
detectedBrowserAutomationFramework,
54+
detectedTestingFramework,
55+
);
56+
if (percyInstructions) {
57+
instructions += formatPercyInstructions(percyInstructions);
58+
}
59+
}
60+
return {
61+
content: [{ type: "text", text: instructions, isError: false }],
62+
};
63+
}
64+
65+
let fullInstructions = "";
66+
// Add language-dependent prefix command
67+
fullInstructions += getSDKPrefixCommand(
68+
detectedLanguage,
69+
detectedTestingFramework,
70+
);
71+
72+
const ymlInstructions = generateBrowserStackYMLInstructions(
73+
desiredPlatforms,
74+
enablePercy,
75+
);
76+
fullInstructions += `${ymlInstructions}`;
77+
3178
const instructionsForProjectConfiguration =
3279
getInstructionsForProjectConfiguration(
3380
detectedBrowserAutomationFramework,
3481
detectedTestingFramework,
3582
detectedLanguage,
3683
);
3784

85+
if (enablePercy) {
86+
const percyInstructions = getPercyInstructions(
87+
detectedLanguage,
88+
detectedBrowserAutomationFramework,
89+
detectedTestingFramework,
90+
);
91+
if (percyInstructions) {
92+
fullInstructions += formatPercyInstructions(percyInstructions);
93+
} else {
94+
fullInstructions += `\n\nNote: Percy SDK instructions for ${detectedLanguage} with ${detectedTestingFramework} are not yet available through this tool. Please refer to the official BrowserStack Percy documentation.`;
95+
}
96+
}
97+
98+
fullInstructions += `\n\nAfter setting up the files above, follow these final steps:\n${instructionsForProjectConfiguration}`;
99+
38100
return {
39101
content: [
40102
{
41103
type: "text",
42-
text: `${instructions}\n\n After creating the browserstack.yml file above, do the following: ${instructionsForProjectConfiguration}`,
104+
text: fullInstructions,
43105
isError: false,
44106
},
45107
],
@@ -49,20 +111,20 @@ export async function bootstrapProjectWithSDK({
49111
export default function addSDKTools(server: McpServer) {
50112
server.tool(
51113
"runTestsOnBrowserStack",
52-
"Use this tool to get instructions for running tests on BrowserStack.",
114+
"Use this tool to get instructions for running tests on BrowserStack and browserstack percy",
53115
{
54116
detectedBrowserAutomationFramework: z
55-
.string()
117+
.nativeEnum(SDKSupportedBrowserAutomationFrameworkEnum)
56118
.describe(
57119
"The automation framework configured in the project. Example: 'playwright', 'selenium'",
58120
),
59121
detectedTestingFramework: z
60-
.string()
122+
.nativeEnum(SDKSupportedTestingFrameworkEnum)
61123
.describe(
62-
"The testing framework used in the project. Be precise with framework selection Example: 'jest', 'pytest', 'junit4', 'junit5', 'mocha'",
124+
"The testing framework used in the project. Be precise with framework selection Example: 'webdriverio', 'jest', 'pytest', 'junit4', 'junit5', 'mocha'",
63125
),
64126
detectedLanguage: z
65-
.string()
127+
.nativeEnum(SDKSupportedLanguageEnum)
66128
.describe(
67129
"The programming language used in the project. Example: 'nodejs', 'python', 'java', 'csharp'",
68130
),
@@ -71,6 +133,13 @@ export default function addSDKTools(server: McpServer) {
71133
.describe(
72134
"The platforms the user wants to test on. Always ask this to the user, do not try to infer this.",
73135
),
136+
enablePercy: z
137+
.boolean()
138+
.optional()
139+
.default(false)
140+
.describe(
141+
"Set to true if the user wants to enable Percy for visual testing. Defaults to false.",
142+
),
74143
},
75144
async (args) => {
76145
try {
@@ -83,6 +152,7 @@ export default function addSDKTools(server: McpServer) {
83152
args.detectedTestingFramework as SDKSupportedTestingFramework,
84153
detectedLanguage: args.detectedLanguage as SDKSupportedLanguage,
85154
desiredPlatforms: args.desiredPlatforms,
155+
enablePercy: args.enablePercy,
86156
});
87157
} catch (error) {
88158
trackMCP(

src/tools/sdk-utils/commands.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Utility to get the language-dependent prefix command for BrowserStack SDK setup
2+
import { SDKSupportedLanguage } from "./types.js";
3+
4+
// Framework mapping for Java Maven archetype generation
5+
const JAVA_FRAMEWORK_MAP: Record<string, string> = {
6+
testng: "testng",
7+
junit: "junit5", // Map generic junit to junit5 as default
8+
cucumber: "cucumber-testng", // Map generic cucumber to cucumber-testng as default
9+
};
10+
11+
export function getSDKPrefixCommand(
12+
language: SDKSupportedLanguage,
13+
framework: string,
14+
): string {
15+
switch (language) {
16+
case "nodejs":
17+
return `Install BrowserStack Node SDK\nusing command | npm i -D browserstack-node-sdk@latest\n| and then run following command to setup browserstack sdk:\n npx setup --username ${process.env.BROWSERSTACK_USERNAME} --key ${process.env.BROWSERSTACK_ACCESS_KEY}\n\n. This will create browserstack.yml file in the project root. Edit the file to add your desired platforms and browsers. If the file is not created :\n`;
18+
19+
case "java": {
20+
const mavenFramework = getJavaFrameworkForMaven(framework);
21+
return `Install BrowserStack Java SDK
22+
23+
**Maven command for ${framework}:**
24+
Run the command, it is required to generate the browserstack-sdk-archetype-integrate project:
25+
mvn archetype:generate -B -DarchetypeGroupId=com.browserstack \\
26+
-DarchetypeArtifactId=browserstack-sdk-archetype-integrate -DarchetypeVersion=1.0 \\
27+
-DgroupId=com.browserstack -DartifactId=browserstack-sdk-archetype-integrate -Dversion=1.0 \\
28+
-DBROWSERSTACK_USERNAME=${process.env.BROWSERSTACK_USERNAME} -DBROWSERSTACK_ACCESS_KEY=${process.env.BROWSERSTACK_ACCESS_KEY} \\
29+
-DBROWSERSTACK_FRAMEWORK=${mavenFramework}
30+
31+
**For Gradle setup:**
32+
1. Add browserstack-java-sdk to dependencies:
33+
compileOnly 'com.browserstack:browserstack-java-sdk:latest.release'
34+
35+
2. Add browserstackSDK path variable:
36+
def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }
37+
38+
3. Add javaagent to gradle tasks:
39+
jvmArgs "-javaagent:\${browserstackSDKArtifact.file}"
40+
`;
41+
}
42+
43+
// Add more languages as needed
44+
default:
45+
return "";
46+
}
47+
}
48+
49+
export function getJavaFrameworkForMaven(framework: string): string {
50+
return JAVA_FRAMEWORK_MAP[framework] || framework;
51+
}

0 commit comments

Comments
 (0)