Skip to content

Add Support to NodeJS Frameworks #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: app-automate
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 132 additions & 54 deletions src/tools/app-sdk-utils/commands.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,162 @@
// Utility to get the language-dependent prefix command for BrowserStack App Automate SDK setup
import { AppSDKSupportedLanguage } from "./types.js";
import {
GRADLE_APP_SETUP_INSTRUCTIONS,
getMavenAppAutomateCommand,
} from "./constants.js";
import { getSetBrowserStackCredentialsStep } from "./utils.js";
import {
AppSDKSupportedLanguageEnum,
AppSDKSupportedFrameworkEnum,
} from "./types.js";

// Framework mapping for Java Maven archetype generation for App Automate
const JAVA_APP_FRAMEWORK_MAP: Record<string, string> = {
testng: "browserstack-sdk-archetype-integrate",
"testng": "browserstack-sdk-archetype-integrate",
"cucumber-testng": "browserstack-sdk-archetype-integrate",
"cucumber-junit4": "browserstack-sdk-archetype-integrate",
"cucumber-junit5": "browserstack-sdk-archetype-integrate",
};

// Common Gradle setup instructions for App Automate (platform-independent)
const GRADLE_APP_SETUP_INSTRUCTIONS = `
**For Gradle setup:**
1. Add browserstack-java-sdk to dependencies:
compileOnly 'com.browserstack:browserstack-java-sdk:latest.release'

2. Add browserstackSDK path variable:
def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }

3. Add javaagent to gradle tasks:
jvmArgs "-javaagent:\${browserstackSDKArtifact.file}"
`;
export function getJavaAppFrameworkForMaven(framework: string): string {
return JAVA_APP_FRAMEWORK_MAP[framework] || framework;
}

export function getAppSDKPrefixCommand(
language: AppSDKSupportedLanguage,
framework: string,
username: string,
accessKey: string,
accessKey: string
): string {
switch (language) {
case "java": {
case AppSDKSupportedLanguageEnum.java: {
const mavenFramework = getJavaAppFrameworkForMaven(framework);
const isWindows = process.platform === "win32";
const mavenCommand = getMavenAppAutomateCommand(
mavenFramework,
framework,
username,
accessKey
);

const frameworkParam = `-DBROWSERSTACK_FRAMEWORK="${framework}"`;
return (
getSetBrowserStackCredentialsStep(username, accessKey) +
`---STEP---
Install BrowserStack SDK using Maven Archetype for App Automate

const mavenCommand = isWindows
? `mvn archetype:generate -B -DarchetypeGroupId="com.browserstack" -DarchetypeArtifactId="${mavenFramework}" -DarchetypeVersion="1.0" -DgroupId="com.browserstack" -DartifactId="${mavenFramework}" -Dversion="1.0" -DBROWSERSTACK_USERNAME="${username}" -DBROWSERSTACK_ACCESS_KEY="${accessKey}" ${frameworkParam}`
: `mvn archetype:generate -B -DarchetypeGroupId=com.browserstack \\
-DarchetypeArtifactId=${mavenFramework} -DarchetypeVersion=1.0 \\
-DgroupId=com.browserstack -DartifactId=${mavenFramework} -Dversion=1.0 \\
-DBROWSERSTACK_USERNAME="${username}" \\
-DBROWSERSTACK_ACCESS_KEY="${accessKey}" \\
${frameworkParam}`;
Maven command for ${framework} (${
process.platform === "win32" ? "Windows" : "macOS/Linux"
}):
\`\`\`bash
${mavenCommand}
\`\`\`

const platformLabel = isWindows ? "Windows" : "macOS/Linux";
Alternative setup for Gradle users:
${GRADLE_APP_SETUP_INSTRUCTIONS}`
);
}

return `---STEP---
Set BrowserStack credentials as environment variables:
case AppSDKSupportedLanguageEnum.nodejs: {
if (framework === AppSDKSupportedFrameworkEnum.webdriverio) {
return (
getSetBrowserStackCredentialsStep(username, accessKey) +
`---STEP---
Install BrowserStack WDIO service:

**${platformLabel}:**
${
isWindows
? `\`\`\`cmd
set BROWSERSTACK_USERNAME=${username}
set BROWSERSTACK_ACCESS_KEY=${accessKey}
\`\`\``
: `\`\`\`bash
export BROWSERSTACK_USERNAME="${username}"
export BROWSERSTACK_ACCESS_KEY="${accessKey}"
\`\`\``
}
\`\`\`bash
npm install @wdio/browserstack-service --save-dev
\`\`\`

---STEP---
Install BrowserStack SDK using Maven Archetype for App Automate
---STEP---
Update your WebdriverIO config file (e.g., \`wdio.conf.js\`) to add the BrowserStack service and capabilities:

**Maven command for ${framework} (${platformLabel}):**
\`\`\`bash
${mavenCommand}
\`\`\`
\`\`\`js
exports.config = {
user: process.env.BROWSERSTACK_USERNAME || '${username}',
key: process.env.BROWSERSTACK_ACCESS_KEY || '${accessKey}',
hostname: 'hub.browserstack.com',
services: [
[
'browserstack',
{
app: 'bs://sample.app',
browserstackLocal: true,
accessibility: false,
testObservabilityOptions: {
buildName: "bstack-demo",
projectName: "BrowserStack Sample",
buildTag: 'Any build tag goes here. For e.g. ["Tag1","Tag2"]'
},
},
]
],
capabilities: [{
'bstack:options': {
deviceName: 'Samsung Galaxy S22 Ultra',
platformVersion: '12.0',
platformName: 'android',
}
}],
commonCapabilities: {
'bstack:options': {
debug: true,
networkLogs: true,
percy: false,
percyCaptureMode: 'auto'
}
},
maxInstances: 10,
// ...other config
};`
);
}
if (framework === AppSDKSupportedFrameworkEnum.nightwatch) {
return (
getSetBrowserStackCredentialsStep(username, accessKey) +
`---STEP---
Install Nightwatch and BrowserStack integration:

Alternative setup for Gradle users:
${GRADLE_APP_SETUP_INSTRUCTIONS}`;
}
\`\`\`bash
npm install nightwatch nightwatch-browserstack --save-dev
\`\`\`

---STEP---
Update your Nightwatch config file (e.g., \`nightwatch.conf.js\`) to add the BrowserStack settings and capabilities:

default:
return "";
\`\`\`js
module.exports = {
src_folders: ["tests"],
test_settings: {
default: {
selenium: {
start_process: false,
host: "hub.browserstack.com",
port: 443,
},
desiredCapabilities: {
"bstack:options": {
userName: process.env.BROWSERSTACK_USERNAME || "${username}",
accessKey: process.env.BROWSERSTACK_ACCESS_KEY || "${accessKey}",
deviceName: "Samsung Galaxy S22 Ultra",
osVersion: "12.0",
projectName: "BrowserStack Sample",
buildName: "bstack-demo",
sessionName: "Nightwatch App Automate Test",
debug: true,
networkLogs: true,
},
app: "bs://sample.app",
platformName: "android",
},
},
},
};
\`\`\`
`
);
}
break;
}
}
}

export function getJavaAppFrameworkForMaven(framework: string): string {
return JAVA_APP_FRAMEWORK_MAP[framework] || framework;
return "";
}
78 changes: 78 additions & 0 deletions src/tools/app-sdk-utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Common Gradle setup instructions for App Automate (platform-independent)
export const GRADLE_APP_SETUP_INSTRUCTIONS = `
**For Gradle setup:**
1. Add browserstack-java-sdk to dependencies:
compileOnly 'com.browserstack:browserstack-java-sdk:latest.release'

2. Add browserstackSDK path variable:
def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }

3. Add javaagent to gradle tasks:
jvmArgs "-javaagent:\${browserstackSDKArtifact.file}"
`;

/**
* Maven archetype constants for App Automate
*/
export const MAVEN_ARCHETYPE_GROUP_ID = "com.browserstack";
export const MAVEN_ARCHETYPE_VERSION = "1.0";

/**
* Returns the Maven command for Windows for App Automate SDK setup
*/
export function getMavenCommandForWindows(
mavenFramework: string,
framework: string,
username: string,
accessKey: string
): string {
return (
`mvn archetype:generate -B ` +
`-DarchetypeGroupId="${MAVEN_ARCHETYPE_GROUP_ID}" ` +
`-DarchetypeArtifactId="${mavenFramework}" ` +
`-DarchetypeVersion="${MAVEN_ARCHETYPE_VERSION}" ` +
`-DgroupId="${MAVEN_ARCHETYPE_GROUP_ID}" ` +
`-DartifactId="${mavenFramework}" ` +
`-Dversion="${MAVEN_ARCHETYPE_VERSION}" ` +
`-DBROWSERSTACK_USERNAME="${username}" ` +
`-DBROWSERSTACK_ACCESS_KEY="${accessKey}" ` +
`-DBROWSERSTACK_FRAMEWORK="${framework}"`
);
}

/**
* Returns the Maven command for macOS/Linux for App Automate SDK setup
*/
export function getMavenCommandForUnix(
mavenFramework: string,
framework: string,
username: string,
accessKey: string
): string {
return (
`mvn archetype:generate -B \\\n` +
`-DarchetypeGroupId=${MAVEN_ARCHETYPE_GROUP_ID} \\\n` +
`-DarchetypeArtifactId=${mavenFramework} -DarchetypeVersion=${MAVEN_ARCHETYPE_VERSION} \\\n` +
`-DgroupId=${MAVEN_ARCHETYPE_GROUP_ID} -DartifactId=${mavenFramework} -Dversion=${MAVEN_ARCHETYPE_VERSION} \\\n` +
`-DBROWSERSTACK_USERNAME="${username}" \\\n` +
`-DBROWSERSTACK_ACCESS_KEY="${accessKey}" \\\n` +
`-DBROWSERSTACK_FRAMEWORK="${framework}"`
);
}

/**
* Utility to generate the Maven command for App Automate SDK setup (platform-aware)
*/
export function getMavenAppAutomateCommand(
mavenFramework: string,
framework: string,
username: string,
accessKey: string
): string {
const isWindows = process.platform === "win32";
if (isWindows) {
return getMavenCommandForWindows(mavenFramework, framework, username, accessKey);
} else {
return getMavenCommandForUnix(mavenFramework, framework, username, accessKey);
}
}
44 changes: 36 additions & 8 deletions src/tools/app-sdk-utils/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AppSDKSupportedFramework,
AppSDKSupportedTestingFramework,
} from "./types.js";
import { AppSDKSupportedLanguageEnum, AppSDKSupportedTestingFrameworkEnum } from "./types.js";

// App Automate specific device configurations
const APP_DEVICE_CONFIGS = {
Expand Down Expand Up @@ -33,8 +34,8 @@ export function generateAppBrowserStackYMLInstructions(
return devices
.map(
(device) => ` - platformName: ${platform}
deviceName: ${device.deviceName}
platformVersion: "${device.platformVersion}"`,
deviceName: ${device.deviceName}
platformVersion: "${device.platformVersion}"`,
)
.join("\n");
})
Expand Down Expand Up @@ -80,8 +81,10 @@ export function getAppInstructionsForProjectConfiguration(
return "";
}
switch (language) {
case "java":
case AppSDKSupportedLanguageEnum.java:
return getJavaAppInstructions(testingFramework);
case AppSDKSupportedLanguageEnum.nodejs:
return getNodejsAppInstructions(testingFramework);
default:
return "";
}
Expand All @@ -90,15 +93,40 @@ export function getAppInstructionsForProjectConfiguration(
function getJavaAppInstructions(
testingFramework: AppSDKSupportedTestingFramework,
): string {
if (testingFramework === "testng") {
if (testingFramework === AppSDKSupportedTestingFrameworkEnum.testng) {
return `---STEP---
Run your App Automate test suite:
Run your App Automate test suite:

\`\`\`bash
mvn test
\`\`\``;
\`\`\`bash
mvn test
\`\`\``;
}
return "";
}

function getNodejsAppInstructions(
testingFramework: AppSDKSupportedTestingFramework,
): string {
if (testingFramework === AppSDKSupportedTestingFrameworkEnum.webdriverio) {
return `---STEP---
Run your App Automate test suite:

\`\`\`bash
npx wdio run ./wdio.conf.js
\`\`\``;
}
else if (testingFramework === AppSDKSupportedTestingFrameworkEnum.nightwatch) {
return `---STEP---
Run your App Automate test suite:
For Android:
\`\`\`bash
npx nightwatch <path to tests> --env browserstack.android
\`\`\`
For iOS:
\`\`\`bash
npx nightwatch <path to tests> --env browserstack.ios
\`\`\``;
}
return "";
}

Expand Down
5 changes: 5 additions & 0 deletions src/tools/app-sdk-utils/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
export enum AppSDKSupportedLanguageEnum {
java = "java",
nodejs = "nodejs",
}
export type AppSDKSupportedLanguage = keyof typeof AppSDKSupportedLanguageEnum;

export enum AppSDKSupportedFrameworkEnum {
appium = "appium",
webdriverio = "webdriverio",
nightwatch = "nightwatch",
}
export type AppSDKSupportedFramework =
keyof typeof AppSDKSupportedFrameworkEnum;
Expand All @@ -14,6 +17,8 @@ export enum AppSDKSupportedTestingFrameworkEnum {
"cucumber-testng" = "cucumber-testng",
"cucumber-junit4" = "cucumber-junit4",
"cucumber-junit5" = "cucumber-junit5",
webdriverio = "webdriverio",
nightwatch = "nightwatch",
}
export type AppSDKSupportedTestingFramework =
keyof typeof AppSDKSupportedTestingFrameworkEnum;
Expand Down
Loading