Skip to content

Commit cc8d932

Browse files
committed
enhance instruction formatting and add step-by-step guidance for BrowserStack SDK setup
1 parent 6f45c72 commit cc8d932

File tree

5 files changed

+333
-183
lines changed

5 files changed

+333
-183
lines changed

src/tools/bstack-sdk.ts

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
33
import { z } from "zod";
4+
import { trackMCP } from "../lib/instrumentation.js";
5+
import { getSDKPrefixCommand } from "./sdk-utils/commands.js";
6+
47
import {
58
SDKSupportedBrowserAutomationFramework,
69
SDKSupportedLanguage,
@@ -9,16 +12,18 @@ import {
912
SDKSupportedBrowserAutomationFrameworkEnum,
1013
SDKSupportedTestingFrameworkEnum,
1114
} from "./sdk-utils/types.js";
15+
1216
import {
1317
generateBrowserStackYMLInstructions,
1418
getInstructionsForProjectConfiguration,
19+
formatInstructionsWithNumbers,
1520
} from "./sdk-utils/instructions.js";
16-
import { trackMCP } from "../lib/instrumentation.js";
21+
1722
import {
1823
formatPercyInstructions,
1924
getPercyInstructions,
2025
} from "./sdk-utils/percy/instructions.js";
21-
import { getSDKPrefixCommand } from "./sdk-utils/commands.js";
26+
2227

2328
/**
2429
* BrowserStack SDK hooks into your test framework to seamlessly run tests on BrowserStack.
@@ -42,36 +47,35 @@ export async function bootstrapProjectWithSDK({
4247
detectedBrowserAutomationFramework === "cypress" ||
4348
detectedTestingFramework === "webdriverio"
4449
) {
45-
let instructions = getInstructionsForProjectConfiguration(
50+
let combinedInstructions = getInstructionsForProjectConfiguration(
4651
detectedBrowserAutomationFramework,
4752
detectedTestingFramework,
4853
detectedLanguage,
4954
);
55+
5056
if (enablePercy) {
5157
const percyInstructions = getPercyInstructions(
5258
detectedLanguage,
5359
detectedBrowserAutomationFramework,
5460
detectedTestingFramework,
5561
);
62+
5663
if (percyInstructions) {
57-
instructions += formatPercyInstructions(percyInstructions);
64+
combinedInstructions +=
65+
"\n\n" + formatPercyInstructions(percyInstructions);
5866
} else {
5967
throw new Error(
6068
`Percy is currently not supported through MCP for ${detectedLanguage} with ${detectedTestingFramework}. If you want to run the test cases without Percy, disable Percy and run it again.`,
6169
);
6270
}
6371
}
64-
return {
65-
content: [{ type: "text", text: instructions, isError: false }],
66-
};
67-
}
6872

69-
let fullInstructions =`⚠️ IMPORTANT: DO NOT SKIP ANY STEP
70-
All the setup steps described in this file MUST be executed regardless of any existing configuration or setup.
71-
This ensures proper BrowserStack SDK setup.`;
73+
// Apply consistent formatting for all configurations
74+
return formatFinalInstructions(combinedInstructions);
75+
}
7276

73-
// Add language-dependent prefix command
74-
fullInstructions += getSDKPrefixCommand(
77+
// Handle default flow using browserstack.yml
78+
const sdkSetupCommand = getSDKPrefixCommand(
7579
detectedLanguage,
7680
detectedTestingFramework,
7781
);
@@ -80,7 +84,6 @@ export async function bootstrapProjectWithSDK({
8084
desiredPlatforms,
8185
enablePercy,
8286
);
83-
fullInstructions += `${ymlInstructions}`;
8487

8588
const instructionsForProjectConfiguration =
8689
getInstructionsForProjectConfiguration(
@@ -89,22 +92,52 @@ export async function bootstrapProjectWithSDK({
8992
detectedLanguage,
9093
);
9194

95+
let combinedInstructions = "";
96+
97+
// Step 1: Add SDK setup command
98+
if (sdkSetupCommand) {
99+
combinedInstructions += sdkSetupCommand;
100+
}
101+
102+
// Step 2: Add browserstack.yml setup
103+
if (ymlInstructions) {
104+
combinedInstructions += "\n\n---STEP---\n" + ymlInstructions;
105+
}
106+
107+
// Step 3: Add language/framework-specific setup
108+
if (instructionsForProjectConfiguration) {
109+
combinedInstructions += "\n\n" + instructionsForProjectConfiguration;
110+
}
111+
112+
// Step 4: Add Percy setup if applicable
92113
if (enablePercy) {
93114
const percyInstructions = getPercyInstructions(
94115
detectedLanguage,
95116
detectedBrowserAutomationFramework,
96117
detectedTestingFramework,
97118
);
119+
98120
if (percyInstructions) {
99-
fullInstructions += formatPercyInstructions(percyInstructions);
121+
combinedInstructions +=
122+
"\n\n" + formatPercyInstructions(percyInstructions);
100123
} else {
101124
throw new Error(
102125
`Percy is currently not supported through MCP for ${detectedLanguage} with ${detectedTestingFramework}. If you want to run the test cases without Percy, disable Percy and run it again.`,
103126
);
104127
}
105128
}
106129

107-
fullInstructions += `\n\nAfter setting up the files above, follow these final steps:\n${instructionsForProjectConfiguration}`;
130+
// Apply consistent formatting for all configurations
131+
return formatFinalInstructions(combinedInstructions);
132+
}
133+
134+
// Helper function to apply consistent formatting to all instruction types
135+
function formatFinalInstructions(combinedInstructions: string): CallToolResult {
136+
const fullInstructions = `⚠️ IMPORTANT: DO NOT SKIP ANY STEP
137+
All the setup steps described in this file MUST be executed regardless of any existing configuration or setup.
138+
This ensures proper BrowserStack SDK setup.
139+
140+
${formatInstructionsWithNumbers(combinedInstructions)}`;
108141

109142
return {
110143
content: [
@@ -127,21 +160,25 @@ export default function addSDKTools(server: McpServer) {
127160
.describe(
128161
"The automation framework configured in the project. Example: 'playwright', 'selenium'",
129162
),
163+
130164
detectedTestingFramework: z
131165
.nativeEnum(SDKSupportedTestingFrameworkEnum)
132166
.describe(
133167
"The testing framework used in the project. Be precise with framework selection Example: 'webdriverio', 'jest', 'pytest', 'junit4', 'junit5', 'mocha'",
134168
),
169+
135170
detectedLanguage: z
136171
.nativeEnum(SDKSupportedLanguageEnum)
137172
.describe(
138173
"The programming language used in the project. Example: 'nodejs', 'python', 'java', 'csharp'",
139174
),
175+
140176
desiredPlatforms: z
141177
.array(z.enum(["windows", "macos", "android", "ios"]))
142178
.describe(
143179
"The platforms the user wants to test on. Always ask this to the user, do not try to infer this.",
144180
),
181+
145182
enablePercy: z
146183
.boolean()
147184
.optional()
@@ -150,16 +187,20 @@ export default function addSDKTools(server: McpServer) {
150187
"Set to true if the user wants to enable Percy for visual testing. Defaults to false.",
151188
),
152189
},
190+
153191
async (args) => {
154192
try {
155193
trackMCP("runTestsOnBrowserStack", server.server.getClientVersion()!);
156194

157195
return await bootstrapProjectWithSDK({
158196
detectedBrowserAutomationFramework:
159197
args.detectedBrowserAutomationFramework as SDKSupportedBrowserAutomationFramework,
198+
160199
detectedTestingFramework:
161200
args.detectedTestingFramework as SDKSupportedTestingFramework,
201+
162202
detectedLanguage: args.detectedLanguage as SDKSupportedLanguage,
203+
163204
desiredPlatforms: args.desiredPlatforms,
164205
enablePercy: args.enablePercy,
165206
});
@@ -169,6 +210,7 @@ export default function addSDKTools(server: McpServer) {
169210
server.server.getClientVersion()!,
170211
error,
171212
);
213+
172214
return {
173215
content: [
174216
{

src/tools/sdk-utils/commands.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,18 @@ export function getSDKPrefixCommand(
2828
): string {
2929
switch (language) {
3030
case "nodejs":
31-
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`;
31+
return `---STEP---
32+
Install BrowserStack Node SDK using command:
33+
\`\`\`bash
34+
npm i -D browserstack-node-sdk@latest
35+
\`\`\`
36+
---STEP---
37+
Run the following command to setup browserstack sdk:
38+
\`\`\`bash
39+
npx setup --username ${process.env.BROWSERSTACK_USERNAME} --key ${process.env.BROWSERSTACK_ACCESS_KEY}
40+
\`\`\`
41+
---STEP---
42+
Edit the browserstack.yml file that was created in the project root to add your desired platforms and browsers.`;
3243

3344
case "java": {
3445
const mavenFramework = getJavaFrameworkForMaven(framework);
@@ -45,11 +56,14 @@ export function getSDKPrefixCommand(
4556

4657
const platformLabel = isWindows ? "Windows" : "macOS/Linux";
4758

48-
return `Install BrowserStack Java SDK
59+
return `---STEP---
60+
Install BrowserStack Java SDK
4961
5062
**Maven command for ${framework} (${platformLabel}):**
5163
Run the command, it is required to generate the browserstack-sdk-archetype-integrate project:
5264
${mavenCommand}
65+
66+
Alternative setup for Gradle users:
5367
${GRADLE_SETUP_INSTRUCTIONS}`;
5468
}
5569

0 commit comments

Comments
 (0)