@browserstack/mcp-server 1.2.2-beta → 1.2.2-beta.1

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.
Files changed (94) hide show
  1. package/dist/lib/inmemory-store.d.ts +1 -0
  2. package/dist/lib/inmemory-store.js +1 -0
  3. package/dist/lib/instrumentation.js +2 -0
  4. package/dist/server-factory.js +2 -0
  5. package/dist/tools/accessibility.js +238 -78
  6. package/dist/tools/accessiblity-utils/auth-config.d.ts +39 -0
  7. package/dist/tools/accessiblity-utils/auth-config.js +125 -0
  8. package/dist/tools/accessiblity-utils/scanner.d.ts +1 -1
  9. package/dist/tools/accessiblity-utils/scanner.js +2 -1
  10. package/dist/tools/add-percy-snapshots.d.ts +5 -0
  11. package/dist/tools/add-percy-snapshots.js +17 -0
  12. package/dist/tools/bstack-sdk.d.ts +2 -15
  13. package/dist/tools/bstack-sdk.js +7 -124
  14. package/dist/tools/list-test-files.d.ts +2 -0
  15. package/dist/tools/list-test-files.js +33 -0
  16. package/dist/tools/percy-sdk.d.ts +4 -0
  17. package/dist/tools/percy-sdk.js +88 -0
  18. package/dist/tools/percy-snapshot-utils/constants.d.ts +16 -0
  19. package/dist/tools/percy-snapshot-utils/constants.js +500 -0
  20. package/dist/tools/percy-snapshot-utils/detect-test-files.d.ts +10 -0
  21. package/dist/tools/percy-snapshot-utils/detect-test-files.js +194 -0
  22. package/dist/tools/percy-snapshot-utils/types.d.ts +15 -0
  23. package/dist/tools/percy-snapshot-utils/utils.d.ts +4 -0
  24. package/dist/tools/percy-snapshot-utils/utils.js +30 -0
  25. package/dist/tools/sdk-utils/{commands.d.ts → bstack/commands.d.ts} +1 -1
  26. package/dist/tools/sdk-utils/bstack/commands.js +88 -0
  27. package/dist/tools/sdk-utils/bstack/configUtils.d.ts +4 -0
  28. package/dist/tools/sdk-utils/bstack/configUtils.js +66 -0
  29. package/dist/tools/sdk-utils/bstack/constants.d.ts +58 -0
  30. package/dist/tools/sdk-utils/{constants.js → bstack/constants.js} +117 -78
  31. package/dist/tools/sdk-utils/{constants.d.ts → bstack/frameworks.d.ts} +1 -1
  32. package/dist/tools/sdk-utils/bstack/frameworks.js +57 -0
  33. package/dist/tools/sdk-utils/bstack/index.d.ts +4 -0
  34. package/dist/tools/sdk-utils/bstack/index.js +5 -0
  35. package/dist/tools/sdk-utils/bstack/sdkHandler.d.ts +4 -0
  36. package/dist/tools/sdk-utils/bstack/sdkHandler.js +74 -0
  37. package/dist/tools/sdk-utils/common/constants.d.ts +10 -0
  38. package/dist/tools/sdk-utils/common/constants.js +86 -0
  39. package/dist/tools/sdk-utils/common/formatUtils.d.ts +5 -0
  40. package/dist/tools/sdk-utils/common/formatUtils.js +27 -0
  41. package/dist/tools/sdk-utils/common/index.d.ts +3 -0
  42. package/dist/tools/sdk-utils/common/index.js +4 -0
  43. package/dist/tools/sdk-utils/common/instructionUtils.d.ts +8 -0
  44. package/dist/tools/sdk-utils/common/instructionUtils.js +20 -0
  45. package/dist/tools/sdk-utils/common/schema.d.ts +61 -0
  46. package/dist/tools/sdk-utils/common/schema.js +28 -0
  47. package/dist/tools/sdk-utils/common/types.d.ts +66 -0
  48. package/dist/tools/sdk-utils/common/types.js +50 -0
  49. package/dist/tools/sdk-utils/common/utils.d.ts +25 -0
  50. package/dist/tools/sdk-utils/common/utils.js +84 -0
  51. package/dist/tools/sdk-utils/handler.d.ts +5 -0
  52. package/dist/tools/sdk-utils/handler.js +144 -0
  53. package/dist/tools/sdk-utils/percy-automate/constants.d.ts +11 -0
  54. package/dist/tools/sdk-utils/percy-automate/constants.js +365 -0
  55. package/dist/tools/sdk-utils/percy-automate/frameworks.d.ts +8 -0
  56. package/dist/tools/sdk-utils/percy-automate/frameworks.js +50 -0
  57. package/dist/tools/sdk-utils/percy-automate/handler.d.ts +3 -0
  58. package/dist/tools/sdk-utils/percy-automate/handler.js +30 -0
  59. package/dist/tools/sdk-utils/percy-automate/index.d.ts +1 -0
  60. package/dist/tools/sdk-utils/percy-automate/index.js +2 -0
  61. package/dist/tools/sdk-utils/percy-automate/types.d.ts +13 -0
  62. package/dist/tools/sdk-utils/percy-automate/types.js +1 -0
  63. package/dist/tools/sdk-utils/percy-bstack/constants.d.ts +4 -0
  64. package/dist/tools/sdk-utils/{percy → percy-bstack}/constants.js +13 -39
  65. package/dist/tools/sdk-utils/percy-bstack/frameworks.d.ts +2 -0
  66. package/dist/tools/sdk-utils/percy-bstack/frameworks.js +27 -0
  67. package/dist/tools/sdk-utils/percy-bstack/handler.d.ts +4 -0
  68. package/dist/tools/sdk-utils/percy-bstack/handler.js +99 -0
  69. package/dist/tools/sdk-utils/percy-bstack/index.d.ts +4 -0
  70. package/dist/tools/sdk-utils/percy-bstack/index.js +4 -0
  71. package/dist/tools/sdk-utils/percy-bstack/instructions.d.ts +7 -0
  72. package/dist/tools/sdk-utils/{percy → percy-bstack}/instructions.js +5 -9
  73. package/dist/tools/sdk-utils/percy-bstack/types.d.ts +13 -0
  74. package/dist/tools/sdk-utils/percy-bstack/types.js +5 -0
  75. package/dist/tools/sdk-utils/percy-web/constants.d.ts +41 -0
  76. package/dist/tools/sdk-utils/percy-web/constants.js +941 -0
  77. package/dist/tools/sdk-utils/percy-web/fetchPercyToken.d.ts +4 -0
  78. package/dist/tools/sdk-utils/percy-web/fetchPercyToken.js +28 -0
  79. package/dist/tools/sdk-utils/percy-web/frameworks.d.ts +7 -0
  80. package/dist/tools/sdk-utils/percy-web/frameworks.js +103 -0
  81. package/dist/tools/sdk-utils/percy-web/handler.d.ts +4 -0
  82. package/dist/tools/sdk-utils/percy-web/handler.js +27 -0
  83. package/dist/tools/sdk-utils/percy-web/index.d.ts +4 -0
  84. package/dist/tools/sdk-utils/percy-web/index.js +4 -0
  85. package/dist/tools/sdk-utils/percy-web/types.d.ts +12 -0
  86. package/dist/tools/sdk-utils/percy-web/types.js +1 -0
  87. package/package.json +1 -1
  88. package/dist/tools/sdk-utils/commands.js +0 -65
  89. package/dist/tools/sdk-utils/instructions.d.ts +0 -6
  90. package/dist/tools/sdk-utils/instructions.js +0 -99
  91. package/dist/tools/sdk-utils/percy/constants.d.ts +0 -3
  92. package/dist/tools/sdk-utils/percy/instructions.d.ts +0 -10
  93. package/dist/tools/sdk-utils/percy/types.d.ts +0 -5
  94. /package/dist/tools/{sdk-utils/percy → percy-snapshot-utils}/types.js +0 -0
@@ -1,128 +1,11 @@
1
- import { z } from "zod";
2
- import { trackMCP } from "../lib/instrumentation.js";
3
- import { getSDKPrefixCommand } from "./sdk-utils/commands.js";
4
- import { SDKSupportedLanguageEnum, SDKSupportedBrowserAutomationFrameworkEnum, SDKSupportedTestingFrameworkEnum, } from "./sdk-utils/types.js";
5
- import { generateBrowserStackYMLInstructions, getInstructionsForProjectConfiguration, formatInstructionsWithNumbers, } from "./sdk-utils/instructions.js";
6
- import { formatPercyInstructions, getPercyInstructions, } from "./sdk-utils/percy/instructions.js";
7
- import { getBrowserStackAuth } from "../lib/get-auth.js";
8
- /**
9
- * BrowserStack SDK hooks into your test framework to seamlessly run tests on BrowserStack.
10
- * This tool gives instructions to setup a browserstack.yml file in the project root and installs the necessary dependencies.
11
- */
12
- export async function bootstrapProjectWithSDK({ detectedBrowserAutomationFramework, detectedTestingFramework, detectedLanguage, desiredPlatforms, enablePercy, config, }) {
13
- // Get credentials from config
14
- const authString = getBrowserStackAuth(config);
15
- const [username, accessKey] = authString.split(":");
16
- // Handle frameworks with unique setup instructions that don't use browserstack.yml
17
- if (detectedBrowserAutomationFramework === "cypress" ||
18
- detectedTestingFramework === "webdriverio") {
19
- let combinedInstructions = getInstructionsForProjectConfiguration(detectedBrowserAutomationFramework, detectedTestingFramework, detectedLanguage, username, accessKey);
20
- if (enablePercy) {
21
- const percyInstructions = getPercyInstructions(detectedLanguage, detectedBrowserAutomationFramework, detectedTestingFramework);
22
- if (percyInstructions) {
23
- combinedInstructions +=
24
- "\n\n" + formatPercyInstructions(percyInstructions);
25
- }
26
- else {
27
- throw new Error(`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.`);
28
- }
29
- }
30
- // Apply consistent formatting for all configurations
31
- return formatFinalInstructions(combinedInstructions);
32
- }
33
- // Handle default flow using browserstack.yml
34
- const sdkSetupCommand = getSDKPrefixCommand(detectedLanguage, detectedTestingFramework, username, accessKey);
35
- const ymlInstructions = generateBrowserStackYMLInstructions(desiredPlatforms, enablePercy);
36
- const instructionsForProjectConfiguration = getInstructionsForProjectConfiguration(detectedBrowserAutomationFramework, detectedTestingFramework, detectedLanguage, username, accessKey);
37
- let combinedInstructions = "";
38
- // Step 1: Add SDK setup command
39
- if (sdkSetupCommand) {
40
- combinedInstructions += sdkSetupCommand;
41
- }
42
- // Step 2: Add browserstack.yml setup
43
- if (ymlInstructions) {
44
- combinedInstructions += "\n\n---STEP---\n" + ymlInstructions;
45
- }
46
- // Step 3: Add language/framework-specific setup
47
- if (instructionsForProjectConfiguration) {
48
- combinedInstructions += "\n\n" + instructionsForProjectConfiguration;
49
- }
50
- // Step 4: Add Percy setup if applicable
51
- if (enablePercy) {
52
- const percyInstructions = getPercyInstructions(detectedLanguage, detectedBrowserAutomationFramework, detectedTestingFramework);
53
- if (percyInstructions) {
54
- combinedInstructions +=
55
- "\n\n" + formatPercyInstructions(percyInstructions);
56
- }
57
- else {
58
- throw new Error(`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.`);
59
- }
60
- }
61
- // Apply consistent formatting for all configurations
62
- return formatFinalInstructions(combinedInstructions);
63
- }
64
- // Helper function to apply consistent formatting to all instruction types
65
- function formatFinalInstructions(combinedInstructions) {
66
- const fullInstructions = `⚠️ IMPORTANT: DO NOT SKIP ANY STEP
67
- All the setup steps described in this file MUST be executed regardless of any existing configuration or setup.
68
- This ensures proper BrowserStack SDK setup.
69
-
70
- ${formatInstructionsWithNumbers(combinedInstructions)}`;
71
- return {
72
- content: [
73
- {
74
- type: "text",
75
- text: fullInstructions,
76
- isError: false,
77
- },
78
- ],
79
- };
80
- }
81
- export default function addSDKTools(server, config) {
1
+ import { RunTestsOnBrowserStackParamsShape } from "./sdk-utils/common/schema.js";
2
+ import { runTestsOnBrowserStackHandler } from "./sdk-utils/handler.js";
3
+ import { RUN_ON_BROWSERSTACK_DESCRIPTION } from "./sdk-utils/common/constants.js";
4
+ export function registerRunBrowserStackTestsTool(server, config) {
82
5
  const tools = {};
83
- tools.setupBrowserStackAutomateTests = server.tool("setupBrowserStackAutomateTests", "Set up and run automated web-based tests on BrowserStack using the BrowserStack SDK. Use for functional or integration tests on BrowserStack, with optional Percy visual testing for supported frameworks. Example prompts: run this test on browserstack; run this test on browserstack with Percy; set up this project for browserstack with Percy. Integrate BrowserStack SDK into your project", {
84
- detectedBrowserAutomationFramework: z
85
- .nativeEnum(SDKSupportedBrowserAutomationFrameworkEnum)
86
- .describe("The automation framework configured in the project. Example: 'playwright', 'selenium'"),
87
- detectedTestingFramework: z
88
- .nativeEnum(SDKSupportedTestingFrameworkEnum)
89
- .describe("The testing framework used in the project. Be precise with framework selection Example: 'webdriverio', 'jest', 'pytest', 'junit4', 'junit5', 'mocha'"),
90
- detectedLanguage: z
91
- .nativeEnum(SDKSupportedLanguageEnum)
92
- .describe("The programming language used in the project. Example: 'nodejs', 'python', 'java', 'csharp'"),
93
- desiredPlatforms: z
94
- .array(z.enum(["windows", "macos", "android", "ios"]))
95
- .describe("The platforms the user wants to test on. Always ask this to the user, do not try to infer this."),
96
- enablePercy: z
97
- .boolean()
98
- .optional()
99
- .default(false)
100
- .describe("Set to true if the user wants to enable Percy for visual testing. Defaults to false."),
101
- }, async (args) => {
102
- try {
103
- trackMCP("runTestsOnBrowserStack", server.server.getClientVersion(), undefined, config);
104
- return await bootstrapProjectWithSDK({
105
- detectedBrowserAutomationFramework: args.detectedBrowserAutomationFramework,
106
- detectedTestingFramework: args.detectedTestingFramework,
107
- detectedLanguage: args.detectedLanguage,
108
- desiredPlatforms: args.desiredPlatforms,
109
- enablePercy: args.enablePercy,
110
- config,
111
- });
112
- }
113
- catch (error) {
114
- trackMCP("runTestsOnBrowserStack", server.server.getClientVersion(), error, config);
115
- return {
116
- content: [
117
- {
118
- type: "text",
119
- text: `Failed to bootstrap project with BrowserStack SDK. Error: ${error}. Please open an issue on GitHub if the problem persists`,
120
- isError: true,
121
- },
122
- ],
123
- isError: true,
124
- };
125
- }
6
+ tools.setupBrowserStackAutomateTests = server.tool("setupBrowserStackAutomateTests", RUN_ON_BROWSERSTACK_DESCRIPTION, RunTestsOnBrowserStackParamsShape, async (args) => {
7
+ return runTestsOnBrowserStackHandler(args, config);
126
8
  });
127
9
  return tools;
128
10
  }
11
+ export default registerRunBrowserStackTestsTool;
@@ -0,0 +1,2 @@
1
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ export declare function addListTestFiles(args: any): Promise<CallToolResult>;
@@ -0,0 +1,33 @@
1
+ import { listTestFiles } from "./percy-snapshot-utils/detect-test-files.js";
2
+ import { testFilePathsMap } from "../lib/inmemory-store.js";
3
+ import crypto from "crypto";
4
+ export async function addListTestFiles(args) {
5
+ const { dirs, language, framework } = args;
6
+ let testFiles = [];
7
+ for (const dir of dirs) {
8
+ const files = await listTestFiles({
9
+ language,
10
+ framework,
11
+ baseDir: dir,
12
+ });
13
+ testFiles = testFiles.concat(files);
14
+ }
15
+ if (testFiles.length === 0) {
16
+ throw new Error("No test files found");
17
+ }
18
+ // Generate a UUID and store the test files in memory
19
+ const uuid = crypto.randomUUID();
20
+ testFilePathsMap.set(uuid, testFiles);
21
+ return {
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: `The Test files are stored in memory with id ${uuid} and the total number of tests files found is ${testFiles.length}. You can use this UUID to retrieve the tests file paths later.`,
26
+ },
27
+ {
28
+ type: "text",
29
+ text: `You can now use the tool addPercySnapshotCommands to update the test file with Percy commands for visual testing with the UUID ${uuid}`,
30
+ },
31
+ ],
32
+ };
33
+ }
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { BrowserStackConfig } from "../lib/types.js";
3
+ export declare function registerPercyTools(server: McpServer, config: BrowserStackConfig): Record<string, any>;
4
+ export default registerPercyTools;
@@ -0,0 +1,88 @@
1
+ import { SetUpPercyParamsShape } from "./sdk-utils/common/schema.js";
2
+ import { updateTestsWithPercyCommands } from "./add-percy-snapshots.js";
3
+ import { addListTestFiles } from "./list-test-files.js";
4
+ import { trackMCP } from "../index.js";
5
+ import { setUpPercyHandler, setUpSimulatePercyChangeHandler, } from "./sdk-utils/handler.js";
6
+ import { SETUP_PERCY_DESCRIPTION, SIMULATE_PERCY_CHANGE_DESCRIPTION, LIST_TEST_FILES_DESCRIPTION, PERCY_SNAPSHOT_COMMANDS_DESCRIPTION, } from "./sdk-utils/common/constants.js";
7
+ import { ListTestFilesParamsShape, UpdateTestFileWithInstructionsParams, } from "./percy-snapshot-utils/constants.js";
8
+ export function registerPercyTools(server, config) {
9
+ const tools = {};
10
+ // Register setupPercyVisualTesting
11
+ tools.setupPercyVisualTesting = server.tool("setupPercyVisualTesting", SETUP_PERCY_DESCRIPTION, SetUpPercyParamsShape, async (args) => {
12
+ try {
13
+ trackMCP("setupPercyVisualTesting", server.server.getClientVersion(), config);
14
+ return setUpPercyHandler(args, config);
15
+ }
16
+ catch (error) {
17
+ trackMCP("setupPercyVisualTesting", server.server.getClientVersion(), error, config);
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: error instanceof Error ? error.message : String(error),
23
+ },
24
+ ],
25
+ isError: true,
26
+ };
27
+ }
28
+ });
29
+ // Register simulatePercyChange
30
+ tools.simulatePercyChange = server.tool("simulatePercyChange", SIMULATE_PERCY_CHANGE_DESCRIPTION, SetUpPercyParamsShape, async (args) => {
31
+ try {
32
+ trackMCP("simulatePercyChange", server.server.getClientVersion(), config);
33
+ return setUpSimulatePercyChangeHandler(args, config);
34
+ }
35
+ catch (error) {
36
+ trackMCP("simulatePercyChange", server.server.getClientVersion(), error, config);
37
+ return {
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: error instanceof Error ? error.message : String(error),
42
+ },
43
+ ],
44
+ isError: true,
45
+ };
46
+ }
47
+ });
48
+ // Register addPercySnapshotCommands
49
+ tools.addPercySnapshotCommands = server.tool("addPercySnapshotCommands", PERCY_SNAPSHOT_COMMANDS_DESCRIPTION, UpdateTestFileWithInstructionsParams, async (args) => {
50
+ try {
51
+ trackMCP("addPercySnapshotCommands", server.server.getClientVersion(), config);
52
+ return await updateTestsWithPercyCommands(args);
53
+ }
54
+ catch (error) {
55
+ trackMCP("addPercySnapshotCommands", server.server.getClientVersion(), error, config);
56
+ return {
57
+ content: [
58
+ {
59
+ type: "text",
60
+ text: error instanceof Error ? error.message : String(error),
61
+ },
62
+ ],
63
+ isError: true,
64
+ };
65
+ }
66
+ });
67
+ // Register listTestFiles
68
+ tools.listTestFiles = server.tool("listTestFiles", LIST_TEST_FILES_DESCRIPTION, ListTestFilesParamsShape, async (args) => {
69
+ try {
70
+ trackMCP("listTestFiles", server.server.getClientVersion(), config);
71
+ return addListTestFiles(args);
72
+ }
73
+ catch (error) {
74
+ trackMCP("listTestFiles", server.server.getClientVersion(), error, config);
75
+ return {
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: error instanceof Error ? error.message : String(error),
80
+ },
81
+ ],
82
+ isError: true,
83
+ };
84
+ }
85
+ });
86
+ return tools;
87
+ }
88
+ export default registerPercyTools;
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import { SDKSupportedLanguage } from "../sdk-utils/common/types.js";
3
+ import { DetectionConfig } from "./types.js";
4
+ export declare const UpdateTestFileWithInstructionsParams: {
5
+ uuid: z.ZodString;
6
+ index: z.ZodNumber;
7
+ };
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
+ export declare const TEST_FILE_DETECTION: Record<SDKSupportedLanguage, DetectionConfig>;
14
+ export declare const EXCLUDED_DIRS: Set<string>;
15
+ export declare const backendIndicators: RegExp[];
16
+ export declare const strongUIIndicators: RegExp[];