Search code examples
seleniumsalesforcerobotframeworkbrowserstack

How to leverage CumulusCI keywords when integrating with BrowserStack?


Unable to understand how to leverage "Open Test Browser" which is a Cumulusci keyword when launching Salesforce url on Browserstack?

Project background: I am building an automation framework (for functional/regression tests) for a Salesforce product using Robot Framework, SeleniumLibrary and CumulusCI and need to scale up automation capabilities to execute same tests on multiple browsers/OS for which I am integrating it with BrowserStack.

Implementation level details: RFW and Cci is integrated correctly and works perfect on any scratch org locally in Chrome or FF. Here I can directly leverage the full power of Cci keywords such as "Open Test Browser" which knows the org details such as instance_url, username and password and has a access token. So logging into the Org is cakewalk. Here launching the SF url does not ask me for a email verification code.

*** Settings ***

Resource  cumulusci/robotframework/Salesforce.robot
Library  cumulusci.robotframework.CumulusCI  ${ORG}
library  SeleniumLibrary  timeout=20
library  OperatingSystem
library  Collections
library  XML
library  String
library  BuiltIn

*** Variables ***
${BSUser}  myBSkey
${BSAccessKey}  s******************b
${BSUrl}  http://${BSUser}:${BSAccessKey}@hub.browserstack.com/wd/hub

###Login Page Locators
${signOn_username}  //input[@id='username']
${signOn_password}  //input[@name='pw']
${loginButton}  //input[@name='Login']

###Home Page Locators
${SetupRecentlyViewed}  //div[@class='module-header']/div/header/h2/span

*** Test Cases ***
Connect RFW with BS
    ${instance_url}  ${username}  ${password}  Log my Org Info  #User keyword
    Setup BS Browser  ${instance_url}  ${username}  ${password}  #User keyword

*** Keywords ***
Log my Org Info
    &{OrgInfoDict}=  Get Org Info  #Cci keyword
    :FOR    ${key}    IN    @{OrgInfoDict.keys()}
    \   ${instance_url}=  Get From Dictionary    ${OrgInfoDict}    instance_url
    \   ${username}=  Get From Dictionary    ${OrgInfoDict}    username
    \   ${password}=  Get From Dictionary    ${OrgInfoDict}    password
    [Return]  ${instance_url}  ${username}  ${password}

Setup BS Browser
    [Arguments]  ${instance_url}  ${username}  ${password}
    Open Browser  url=${instance_url}  remote_url=${BSUrl}  desired_capabilities=browser:Safari,browser_version:12.0,os:OS X,os_version:Mojave,browserstack.video:True
    Maximize Browser Window
    Login to Salesforce  ${username}  ${password}

Login to Salesforce  [Arguments]  ${Username}  ${Password}
    Input Text  ${signOn_username}  ${Username}
    Input Text  ${signOn_password}  ${Password}
    Click Element  ${loginButton}
    ${Pass}=  RUN KEYWORD AND RETURN STATUS  Wait Until Page Contains Element  ${SetupRecentlyViewed}
    run keyword if  '${Pass}'=='True'  Log  "SF Home page loaded successfully"
    ...  ELSE  Fail  "SF Home page did not load successfully"


Actual Issue: After referring to RFW and BrowserStack integrations on the internet (some links below), I was able to connect to BS but using Selenium keyword "Open Browser". I also tried to get all of my Org info and pass it on to BS to log into the SF url. When I do this, because I am using Selenium and not in the context of Cci, my SF org now throws email verification at me. Hence I feel I am falling short of understanding how to make use of the Cci context when running tests on BrowserStack. Ref: https://www.swtestacademy.com/browserstack-robotframework-integration/ and https://github.com/knightjacky/Robot-BrowserStack

Workarounds tried: I tried creating a webdriver and then using "Open Test Browser" that one also doesnt work, because as expected, it does not have a context of Cci Org.

*** Keywords ***
Create a BS WebDriver
   #Some code that creates a dict...
   #${executor}=  Evaluate  str('${BSUrl}')
   #Create Webdriver  Remote  desired_capabilities=${desired_capabilities}  command_executor=${executor}
   #Open Test Browser  #Cci keyword

Expected thoughts: Please share some ideas as to how I can tweak my current implementation to make use of Cci keywords and not rely on Selenium when integrating with BrowserStack.


Solution

  • At the moment, the salesforce keyword Open test browser doesn't support using the create webdriver keyword. However, it's easy to duplicate what Open test browser does. The key is to use a URL which contains the properly encoded credentials.

    The keyword Login URL from the CumulusCI library will return you an appropriate url. You can then use this url with any browser no matter how the browser was opened.

    Example:

    The following example will use a default browser on browserstack and then logs in to my default org. You can also pass an org into the Login URL keyword if you wish.

    *** Settings ***
    Resource        cumulusci/robotframework/Salesforce.robot
    Suite Setup     Setup BS Browser
    Suite Teardown  Delete records and close browser
    
    *** Variables ***
    ${BSUser}       <your username here>
    ${BSAccessKey}  <your access key here>
    ${BSUrl}        http://${BSUser}:${BSAccessKey}@hub.browserstack.com:80/wd/hub
    
    *** Keywords ***
    Setup BS Browser
        Create Webdriver  Remote   command_executor=${BSUrl}
        ${login_url}  Login URL
        go to  ${login_url}
        Wait until loading is complete
    
    *** Test Cases ***
    Example using 'create webdriver'
        capture page screenshot    
    

    Note: The salesforce keyword Open Test Browser does a bit more than just open the browser: it also installs two location strategies. If you're not calling Open Test Browser and you want to use those location strategies, you will need to register them yourself:

    Add Location Strategy  text   Locate Element By Text
    Add Location Strategy  title  Locate Element By Title