Skip to main content

Integrate BrowserStack Automate with Semaphore

A guide to help you integrate Semaphore with the BrowserStack device cloud for running all your tests.

Introduction

Semaphore is a cloud-based automation service that lets you test and deploys code at the push of a button with hosted continuous integration and delivery. Semaphore offers a clutter-free UI and visual Workflow Builder offers effective pipeline visualizations. Semaphore is free for open-source projects. If you are new to Semaphore or CICD in general, you can read more about it here

In this guide, you’ll learn how to:

Prerequisites

  • BrowserStack Username and Access key, which you can find in your account settings. If you have not created an account yet, you can sign up for a Free Trial or purchase a plan.
  • Your Semaphore CI account credentials.
  • An SCM repository on Github or Bitbucket for which you want to activate the CI pipeline and collaborator access to it.

Set up a pipeline in Semaphore

To create a pipeline in Semaphore, complete the following steps:

  1. Go to Semaphore CI and create an organization where you plan to host the project.
  2. Create BrowserStack credential secret for the pipeline. Secrets are used to store and retrieve sensitive data, such as API keys, which should never be committed to source control.
    To add your BrowserStack account credentials to Semaphore:
    • Go to your Organization and click Settings.
    • Under Secrets, click New Secret.
    • Enter the BrowserStack account credentials as two environment variables, namely BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY. Workflow setup
    • Click Save Secret to save the credentials. Browserstack credentials in Semaphore Organization
  3. Sign in to your Semaphore Organization and connect your repository. You can either use a template starter workflow or customize it in the workflow builder. In your workflow editor for the project, click the Secrets tab, and verify that the BrowserStack credentials secret is selected. You can follow the official Semaphore Guide to create a project. Workflow setup
  4. Click Run the Workflow to generate a new branch set-up-semaphore along with semaphore.yml configuration file. The following code shows a sample configuration file.
     version: v1.0
       name: Test MyApp
       agent:
         machine:
           type: e1-standard-2
           os_image: ubuntu2004
       blocks:
         - name: Build and Test
           task:
             jobs:
               - name: E2E Test on Browserstack
                 commands:
                   - checkout
                   - sem-version node 12
                   - cache restore
                   - npm install
                   - cache store
                   - npm run test
             secrets:
               - name: Browserstack Creds
    
  5. After the pipeline setup is complete, commit and push your changes to the integrated SCM repository that you used to set the Semaphore pipeline.
  6. Open the Semaphore CI dashboard, click Projects and select your project.
  7. View your test result on the Browserstack Automate Dashboard.

Integrate existing test cases

In order to integrate your existing test cases to BrowserStack, ensure that you have added the BrowserStack Capabilities, Credentials, and Remote URL before creating the Remote WebDriver. You can use the environment variables to pass the credentials to your test scripts.

Though your existing test scripts include capabilities, BrowserStack also provides specific capabilities that help determine how tests are run. The following example code snippet sets the os to Windows and the browser to Chrome, declares Username and Access Key from environment variables and creates a remote driver connection.

Using the default SEMAPHORE_JOB_NAME and SEMAPHORE_JOB_ID environment variables in the BrowserStack build name helps generate a unique build name for every test run. To learn more about this environment variable, check out the Semaphore Environment Variables Reference page.

String username = System.getenv("BROWSERSTACK_USERNAME");
String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
String buildName = System.getenv("SEMAPHORE_JOB_NAME");
String buildID = System.getenv("SEMAPHORE_JOB_ID");
  
MutableCapabilities capabilities = new MutableCapabilities();
HashMap<String, Object> browserstackOptions = new HashMap<String, Object>();
browserstackOptions.put("buildName", "semaphore-" + buildName + "-" + buildID);
browserstackOptions.put("seleniumVersion", "4.0.0");
  
capabilities.setCapability("bstack:options", browserstackOptions);
   
WebDriver driver = new RemoteWebDriver(new URL("https://" + username + ":" + accessKey + "@hub.browserstack.com/wd/hub"), capabilities);
username = process.env.BROWSERSTACK_USERNAME
accessKey = process.env.BROWSERSTACK_ACCESS_KEY
buildName = process.env.SEMAPHORE_JOB_NAME
buildID = process.env.SEMAPHORE_JOB_ID

var capabilities = {
  'bstack:options' : {
    "buildName" : "semaphore-" + buildName + "-" + buildID,
    "userName" : username,
    "accessKey" : accessKey,
    "seleniumVersion" : "4.0.0",
  },
}

var driver = new webdriver.Builder().
  usingServer("https://hub-cloud.browserstack.com/wd/hub").
  withCapabilities(capabilities).
  build();
String username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
String accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
String buildName = Environment.GetEnvironmentVariable("SEMAPHORE_JOB_NAME");
String buildID = Environment.GetEnvironmentVariable("SEMAPHORE_JOB_ID");

ChromeOptions capabilities = new ChromeOptions();
Dictionary<string, object> browserstackOptions = new Dictionary<string, object>();
browserstackOptions.Add("buildName", "Semaphore-" + buildName + "-" + buildID);
browserstackOptions.Add("userName", username);
browserstackOptions.Add("accessKey", accessKey);

capabilities.AddAdditionalOption("bstack:options", browserstackOptions);
driver = new RemoteWebDriver(new Uri("https://hub.browserstack.com/wd/hub/"), capabilities);

$username = getenv('BROWSERSTACK_USERNAME');
$accessKey = getenv('BROWSERSTACK_ACCESS_KEY');
$buildName = getenv('SEMAPHORE_JOB_NAME');
$buildID = getenv('SEMAPHORE_JOB_ID');

$caps = array(
	'bstack:options' => array(
		"buildName" => "semaphore-" + $buildName + "-" + $buildID,
		"seleniumVersion" => "4.0.0",
	),
);

$web_driver = RemoteWebDriver::create(
  "https://".$username.":".$accessKey."@hub-cloud.browserstack.com/wd/hub",
  $caps
);
username = os.environ.get('BROWSERSTACK_USERNAME')
accessKey = os.environ.get('BROWSERSTACK_ACCESS_KEY')
buildName = os.environ.get("SEMAPHORE_JOB_NAME");
buildID = os.environ.get("SEMAPHORE_JOB_ID");

desired_cap = {
    'bstack:options' : {
        "buildName" : "semaphore-" + buildName + "-" + buildID,
        "seleniumVersion" : "4.0.0",
        "userName": username,
        "accessKey": accessKey
        },
    }

options = ChromeOptions()
options.set_capability('bstack:options', bstack_options)
driver = webdriver.Remote(
    command_executor="https://hub.browserstack.com/wd/hub",
    options=options)
username = ENV['BROWSERSTACK_USERNAME']
accessKey = ENV['BROWSERSTACK_ACCESS_KEY']
buildName = ENV['SEMAPHORE_JOB_NAME']
buildID = ENV['SEMAPHORE_JOB_ID']

# to run on Chrome
options = Selenium::WebDriver::Options.chrome
capabilities = {
  'bstack:options' => {
    "buildName" => "semaphore-" + buildName + "-" + buildID,
    "seleniumVersion" => "4.0.0",
  },
}
  
options.add_option('bstack:options', bstack_options)
driver = Selenium::WebDriver.for(:remote,
  :url => "https://"+username+":"+accessKey+"@hub.browserstack.com/wd/hub",
  :capabilities => options)
my $username = $ENV{"BROWSERSTACK_USERNAME"};
my $accessKey = $ENV{"BROWSERSTACK_ACCESS_KEY"};
my $buildName = $ENV{"SEMAPHORE_JOB_NAME"};
my $buildID = $ENV{"SEMAPHORE_JOB_ID"};

my $caps = {
  'bstack:options' => {
    "buildName" => "semaphore-" + $buildName + "-" + $buildID,
    "seleniumVersion" => "4.0.0",
    },
  }

my $host = "$username:$accessKey\@hub-cloud.browserstack.com";

my $driver = new Selenium::Remote::Driver('remote_server_addr' => $host,
  'port' => '80', 'extra_capabilities' => $caps);
String username = System.getenv("BROWSERSTACK_USERNAME");
String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
String buildName = System.getenv("SEMAPHORE_JOB_NAME");
String buildID = System.getenv("SEMAPHORE_JOB_ID");

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("os", "Windows");
capabilities.setCapability("os_version", "10");
capabilities.setCapability("browser", "Chrome");
capabilities.setCapability("browser_version", "latest");
capabilities.setCapability("name", "BStack-[Semaphore] Sample Test");
capabilities.setCapability("build", "semaphore-" + buildName + "-" + buildID);
capabilities.setCapability("browserstack.user", username);
capabilities.setCapability("browserstack.key", accessKey);
driver = new RemoteWebDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"), capabilities);
username = process.env.BROWSERSTACK_USERNAME
accessKey = process.env.BROWSERSTACK_ACCESS_KEY
buildName = process.env.SEMAPHORE_JOB_NAME
buildID = process.env.SEMAPHORE_JOB_ID

var capabilities = {
  "os" : "Windows",
  "os_version" : "10",
  "browser" : "chrome",
  "browser_version" : "latest",
  "name": "BStack-[Semaphore] Sample Test"
  "build" : "semaphore-" + buildName + "-" + buildID
  "browserstack.user" : username,
  "browserstack.key" : accessKey,
}

var driver = new webdriver.Builder().
  usingServer("https://hub-cloud.browserstack.com/wd/hub").
  withCapabilities(capabilities).
  build();
String username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
String accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
String buildName = Environment.GetEnvironmentVariable("SEMAPHORE_JOB_NAME");
String buildID = Environment.GetEnvironmentVariable("SEMAPHORE_JOB_ID");

ChromeOptions capability = new ChromeOptions();
capability.AddAdditionalCapability("os", "Windows", true);
capability.AddAdditionalCapability("os_version", "10", true);
capability.AddAdditionalCapability("browser", "Chrome", true);
capability.AddAdditionalCapability("browser_version", "latest", true);
capability.AddAdditionalCapability("name", "BStack-[Semaphore] Sample Test", true);
capability.AddAdditionalCapability("build", "Semaphore-" + buildName + "-" + buildID, true);
capability.AddAdditionalCapability("browserstack.user", username, true);
capability.AddAdditionalCapability("browserstack.key", accessKey, true);
driver = new RemoteWebDriver(new Uri("https://hub-cloud.browserstack.com/wd/hub/"), capability);
$username = getenv('BROWSERSTACK_USERNAME');
$accessKey = getenv('BROWSERSTACK_ACCESS_KEY');
$buildName = getenv('SEMAPHORE_JOB_NAME');
$buildID = getenv('SEMAPHORE_JOB_ID');

$caps = array(
  "os" => "Windows",
  "os_version" => "10",
  "browser" => "Chrome",
  "browser_version" => "latest",
  "name" => "BStack-[Semaphore] Sample Test",
  "build" => "semaphore-" + buildName + "-" + buildID,
  "browserstack.user" => username,
  "browserstack.key" => accessKey
);
$web_driver = RemoteWebDriver::create("https://hub-cloud.browserstack.com/wd/hub", $caps);
username = os.environ.get('BROWSERSTACK_USERNAME')
accessKey = os.environ.get('BROWSERSTACK_ACCESS_KEY')
buildName = os.environ.get("SEMAPHORE_JOB_NAME");
buildID = os.environ.get("SEMAPHORE_JOB_ID");

desired_cap = {
 'os': 'Windows',
 'os_version': '10',
 'browser': 'Chrome',
 'browser_version': 'latest',
 'name': 'BStack-[Semaphore] Sample Test'
 'build': "semaphore-" + buildName + "-" + buildID
 'browserstack.user': username,
 'browserstack.key': accessKey,
}
driver = webdriver.Remote(
    command_executor='https://hub-cloud.browserstack.com/wd/hub',
    desired_capabilities=desired_cap
)
username = ENV['BROWSERSTACK_USERNAME']
accessKey = ENV['BROWSERSTACK_ACCESS_KEY']
buildName = ENV['SEMAPHORE_JOB_NAME']
buildID = ENV['SEMAPHORE_JOB_ID']

caps = Selenium::WebDriver::Remote::Capabilities.new
caps["os"] = "Windows"
caps["os_version"] = "10"
caps["browser"] = "Chrome"
caps["browser_version"] = "latest"
caps['name'] = 'BStack-[Semaphore] Sample Test'
caps['build'] = "semaphore-" + buildName + "-" + buildID
caps['browserstack.user'] = username
caps['browserstack.key'] = accessKey

driver = Selenium::WebDriver.for(:remote,
  :url => 'https://hub-cloud.browserstack.com/wd/hub',
  :desired_capabilities => caps)
my $username = $ENV{"BROWSERSTACK_USERNAME"};
my $accessKey = $ENV{"BROWSERSTACK_ACCESS_KEY"};
my $buildName = $ENV{"SEMAPHORE_JOB_NAME"};
my $buildID = $ENV{"SEMAPHORE_JOB_ID"};

my $caps = {
  "os" => "Windows",
  "os_version" => "10",
  "browser" => "chrome",
  "browser_version" => "latest",
  "name" => "BStack-[Semaphore] Sample Test",
  "build" => "semaphore-" + buildName + "-" + buildID,
  "browserstack.user" => username,
  "browserstack.key" => accessKey
};

my $host = "hub-cloud.browserstack.com";

my $driver = new Selenium::Remote::Driver('remote_server_addr' => $host,
  'port' => '80', 'extra_capabilities' => $caps);

Integrate test cases for locally hosted websites

If you are testing websites hosted locally as part of your testing or development environment, you need to configure your Semaphore pipeline to use Local testing. Ensure that the Internal Testing or development environment are available and accessible on the network where Semaphore is running.

Using the Local testing feature of BrowserStack, remote browsers at the BrowserStack cloud can access websites hosted on your private or internal networks. To learn more about how Local testing works, check out the Local testing guide.

Apart from setting up a Local connection, you must also add the browserstack.local capability in your test scripts.

This section guides how to:

  1. Enable Local testing
  2. Add the browserstack.local capability to test scripts

Enable Local Testing

You can enable Local testing using the ways as shown in the following tab:

Using Local binary, the remote browsers in the BrowserStack cloud are able to access your private or locally-hosted website through the connection established between BrowserStack and the Local binary running on your machine.

To create Semaphore pipeline that uses BrowserStack Local, complete the following steps:

  1. Complete steps 1-6 mentioned in the [Setup a Semaphore pipeline]((#set-up-a-pipeline-in-semaphore) section.
  2. Under the commands section, along with the commands that your tests need to run, add the following commands based on your OS. These commands use the --daemon start and --daemon stop flags to start and stop Local binary respectively. To learn about additional flags used in running Local binary, check out the Binary parameter guide.
     # For Linux-based systems, add the following commands in the given console to download the binary, run it, and stop its execution after the test has been executed.
     $ wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip"
     $ unzip BrowserStackLocal-linux-x64.zip
     $ ./BrowserStackLocal --key $BROWSERSTACK_ACCESS_KEY --daemon start
     $ <your-test-command>
     $ ./BrowserStackLocal --key $BROWSERSTACK_ACCESS_KEY --daemon stop
    
     # For macOS-based systems, add the following commands in the given console to download the binary, run it, and stop its execution after the test has been executed.
     $ wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-darwin-x64.zip"
     $ unzip BrowserStackLocal-darwin-x64.zip
     $ ./BrowserStackLocal --key $BROWSERSTACK_ACCESS_KEY --daemon start
     $ <your-test-command>
     $ ./BrowserStackLocal --key $BROWSERSTACK_ACCESS_KEY --daemon stop
    
     # For Windows-based systems, add the following commands in the given console to download the binary, run it, and stop its execution after the test has been executed.
     $ wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-win32.zip"
     $ powershell.exe Expand-Archive BrowserStackLocal-win32.zip
     $ ./BrowserStackLocal-win32/BrowserStackLocal.exe --key %BROWSERSTACK_ACCESS_KEY% --daemon start
     $ <your-test-command>
     $ ./BrowserStackLocal-win32/BrowserStackLocal.exe --key %BROWSERSTACK_ACCESS_KEY% --daemon stop
    
  3. Save the .semaphore.yml file, push it in your repository and run a New Build.

Note: To download another Local binary version, check out the releases and downloads section.

If you prefer to manage the Local connection through your test scripts, you can use the language bindings.

Check out the enabling Local testing using language bindings guide to edit your test scripts.

Note: Ensure to complete the steps mentioned in the set up Semaphore pipeline section to create your Semaphore pipeline.

Important: Apart from these configurations, you can set other Local options, such as, testing behind a proxy, folder testing, or using multiple local instances. Check out Introduction to Local Testing for more information.

Add browserstack.local capability to test scripts

Add the browserstack.local capability to test scripts using the following code snippets. When you set this capability to true, BrowserStack resolves the request via the Local agent running in your network.

browserstackOptions.put("local", "true");
'bstack:options' : {
	"local" : "true",
},
browserstackOptions.Add("local", "true");
'bstack:options' => array(
	"local" => "true",
),
'bstack:options' : {
	"local" : "true",
},
'bstack:options' => {
	"local" => "true",
},
'bstack:options' : {
	"local" : "true",
},
capabilities.setCapability("browserstack.local", "true");
"browserstack.local" : "true",
capability.AddAdditionalCapability("browserstack.local", "true", true);
"browserstack.local" => "true",
"browserstack.local" : "true",
caps["browserstack.local"] = "true",
"browserstack.local" => "true",

Post these configurations, you should be able to run tests on your locally hosted websites on BrowserStack Automate.

You can verify if the test passed or failed on the Semaphore Dashboard, as shown in the following image. View Logs in Semaphore

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback

Is this page helping you?

Yes
No

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback!

Talk to an Expert
Talk to an Expert