handler.ts•4.91 kB
// Percy + BrowserStack SDK combined handler
import { RunTestsInstructionResult, RunTestsStep } from "../common/types.js";
import { RunTestsOnBrowserStackInput } from "../common/schema.js";
import { getBrowserStackAuth } from "../../../lib/get-auth.js";
import { getSDKPrefixCommand } from "../bstack/commands.js";
import { generateBrowserStackYMLInstructions } from "../bstack/configUtils.js";
import { getInstructionsForProjectConfiguration } from "../common/instructionUtils.js";
import {
  formatPercyInstructions,
  getPercyInstructions,
} from "./instructions.js";
import { BrowserStackConfig } from "../../../lib/types.js";
import {
  SDKSupportedBrowserAutomationFramework,
  SDKSupportedTestingFramework,
  SDKSupportedLanguage,
} from "../common/types.js";
export function runPercyWithBrowserstackSDK(
  input: RunTestsOnBrowserStackInput,
  config: BrowserStackConfig,
): RunTestsInstructionResult {
  const steps: RunTestsStep[] = [];
  const authString = getBrowserStackAuth(config);
  const [username, accessKey] = authString.split(":");
  // Check if Percy is supported for this configuration
  const percyResult = getPercyInstructions(
    input.detectedLanguage as SDKSupportedLanguage,
    input.detectedBrowserAutomationFramework as SDKSupportedBrowserAutomationFramework,
    input.detectedTestingFramework as SDKSupportedTestingFramework,
  );
  if (!percyResult) {
    // Percy not supported for this configuration
    return {
      steps: [
        {
          type: "error",
          title: "Percy Not Supported",
          content: `Percy is not supported for this ${input.detectedBrowserAutomationFramework} framework configuration. Please use BrowserStack SDK only mode or try a different framework combination.`,
          isError: true,
        },
      ],
      requiresPercy: true,
      shouldSkipFormatting: true,
      missingDependencies: [],
    };
  }
  // Handle frameworks with unique setup instructions that don't use browserstack.yml
  if (
    input.detectedBrowserAutomationFramework === "cypress" ||
    input.detectedTestingFramework === "webdriverio"
  ) {
    const frameworkInstructions = getInstructionsForProjectConfiguration(
      input.detectedBrowserAutomationFramework as SDKSupportedBrowserAutomationFramework,
      input.detectedTestingFramework as SDKSupportedTestingFramework,
      input.detectedLanguage as SDKSupportedLanguage,
      username,
      accessKey,
    );
    if (frameworkInstructions && frameworkInstructions.setup) {
      steps.push({
        type: "instruction",
        title: "Framework-Specific Setup",
        content: frameworkInstructions.setup,
      });
    }
    steps.push({
      type: "instruction",
      title: "Percy Setup (BrowserStack SDK + Percy)",
      content: formatPercyInstructions(percyResult),
    });
    if (frameworkInstructions && frameworkInstructions.run) {
      steps.push({
        type: "instruction",
        title: "Run the tests",
        content: frameworkInstructions.run,
      });
    }
    return {
      steps,
      requiresPercy: true,
      missingDependencies: [],
    };
  }
  // Default flow using browserstack.yml with Percy
  const sdkSetupCommand = getSDKPrefixCommand(
    input.detectedLanguage as SDKSupportedLanguage,
    input.detectedTestingFramework as SDKSupportedTestingFramework,
    username,
    accessKey,
  );
  if (sdkSetupCommand) {
    steps.push({
      type: "instruction",
      title: "Install BrowserStack SDK",
      content: sdkSetupCommand,
    });
  }
  const ymlInstructions = generateBrowserStackYMLInstructions(
    {
      platforms:
        ((input as any).devices as string[][] | undefined)?.map((t) =>
          t.join(" "),
        ) || [],
      enablePercy: true,
      projectName: input.projectName,
    },
    config,
  );
  if (ymlInstructions) {
    steps.push({
      type: "instruction",
      title: "Configure browserstack.yml",
      content: ymlInstructions,
    });
  }
  const frameworkInstructions = getInstructionsForProjectConfiguration(
    input.detectedBrowserAutomationFramework as SDKSupportedBrowserAutomationFramework,
    input.detectedTestingFramework as SDKSupportedTestingFramework,
    input.detectedLanguage as SDKSupportedLanguage,
    username,
    accessKey,
  );
  if (frameworkInstructions && frameworkInstructions.setup) {
    steps.push({
      type: "instruction",
      title: "Framework-Specific Setup",
      content: frameworkInstructions.setup,
    });
  }
  steps.push({
    type: "instruction",
    title: "Percy Setup (BrowserStack SDK + Percy)",
    content: formatPercyInstructions(percyResult),
  });
  if (frameworkInstructions && frameworkInstructions.run) {
    steps.push({
      type: "instruction",
      title: "Run the tests",
      content: frameworkInstructions.run,
    });
  }
  return {
    steps,
    requiresPercy: true,
    missingDependencies: [],
  };
}