Integrate Protractor with Universal Agent

This topic describes the steps to integrate Protractor with Universal Agent.

For the most up-to-date instructions and code to use for integrating Protractor with Universal Agent, refer to https://github.com/QASymphony/protractor-sample.
The sample source code for the Protractor project is located at https://github.com/QASymphony/protractor-sample.

Prerequisites

  • Install Git.

  • Install Node.js version 12+.

  • Protractor is installed globally using npm install -g protractor. After installation, verify that Protractor is working using protractor --version.

  • Update webdriver using the following command: webdriver-manager update

  • Clone this source code to your local machine.

    • For Mac or Linux, clone the source code at /usr/local/var/protractor-sample.

    • For Windows, clone the source code at D:\protractor-sample.

Setup

  1. For Mac or Linux, open the terminal.

    or

    For Windows, open the command prompt.

  2. Navigate to the source code folder.

    • For Mac or Linux, navigate to cd /usr/local/var/protractor-sample.

    • For Windows, navigate to cd "D:\protractor-sample".

  3. Run npm run setup to install the required node modules.

Run a Protractor test from the command line

Before integrating Protractor with Universal Agent, verify that you can run a Protractor test from the command line.

  1. Run npm run start-webdriver to start WebDriver from the terminal.

  2. Open another terminal or command prompt instance.

  3. Navigate to the source code folder.

    • For Mac or Linux, navigate to cd /usr/local/var/protractor-sample.

    • For Windows, navigate to cd "D:\protractor-sample".

  4. Run npm run test to execute the Protractor test.

Integrate Protractor with Universal Agent

  1. Download and install qTest Automation Host.

  2. Open a web browser and navigate to the Automation Host screen at http://localhost:6789.

    6789 is the default port for the Automation Host installation. Replace 6789 with the port number you used for installation, if it differs.
  3. Click + New Agent to create a new agent.

    The New Agent window appears.

  4. Enter the following information for each field.

    • Agent Name. Enter the name for the new agent, such as Protractor Universal Agent.

    • qTest Manager Project. Select the qTest Manager project from which the agent is going to execute scheduled tests.

    • Agent Type. Select Universal Agent.

  5. In the Pre-Execute Script field, enter one of the following scripts, based on your operating system.

    Mac

    Copy
    #!/bin/bash
    if [ ! -d "/usr/local/var/protractor-sample" ]
    then
      cd "/usr/local/var"
      git clone git@github.com:QASymphony/protractor-sample.git
    else
      cd /usr/local/var/protractor-sample
      git pull --all
    fi

    Windows

    Copy
    if not exist "D:\protractor-sample" (
     cd /d D:\
     git clone https://github.com/QASymphony/protractor-sample
    ) else (
     cd /d "D:\protractor-sample"
     git pull --all
    )
  6. Enter the following information for each field.

    • Executor. Select node.

    • Working Directory. Select one of the following working directory locations, based on your operating system.

      • For Mac or Linux, select /usr/local/var/protractor-sample.

      • For Windows, select D:\protractor-sample.

  7. In the Execute Command field, enter the following script.

    Copy
    var http = require("http");
    var util = require("../utils");

    const RETRY_THRESHOLDS = 10;
    let retryCount = 0;
    function waitForWebDriverReady(options, callback) {
      var retryOrStop = () => {
        if (retryCount < RETRY_THRESHOLDS) {
          retryCount++;
          // wait for 1 second and retry
          return setTimeout(() => { waitForWebDriverReady(options, callback) }, 1000);
        } else {
          return callback(false);
        }
      }
      const req = http.request(options, res => {
          // webdriver returns 302 Redirect status code when it's ready
        if (res.statusCode === 302) {
          return callback(true);
        } else {
          return retryOrStop();
        }
      });
      req.on('error', (err) => {
        return retryOrStop();
      });
      req.end();
    };

    const { spawn, execSync } = require('child_process');

    // install node module with below command
    execSync('npm run setup', {
      cwd: process.cwd(),
      stdio: 'inherit'
    });

    /* 
    * start webdriver asynchronously 
    */
    var npm;
    const os = require('os');
     if (os.platform() === 'win32')  {
         npm = 'npm.cmd';
     }
    else{
        npm ='npm';
    }
    var childProcesses = spawn(npm, ['run', 'start-webdriver'], { 
        detached: true,
        cwd: process.cwd(),
        stdio: 'inherit'
    });



    var webDriverRequestOptions = {
      host: 'localhost',
      protocol: 'http:',
      port: 4444,
      path: '/wd/hub',
      method: 'GET'
    };

    // let's do our biz
    waitForWebDriverReady(webDriverRequestOptions, (ready) => {
      try {
        if (ready) {
          console.log('Kickoff Protractor test...');
          // build protractor execute command, what it does:
          // 1. if there is no test case being specified, the command is: `npm run test`
          // 2. else, the command should be like this: `npm run test -- --grep="<test case name 1>|<test case name 2>|<test case name n>"`. Reference: https://stackoverflow.com/a/50310279

          // this is the default execute command that will run all specs
          let testCommand = 'npm run test';
          // get scheduled test cases' automation content from magic variable $TESTCASES_AC
          let testcases_ac = $TESTCASES_AC;
          // if there is/are test cases/runs being scheduled, the testcases_ac
          // will have value something like: "<spec name 1>#<test case name 1>,<spec name 2>#<test case name 2>,<spec name N>#<test case name N>"
          if (testcases_ac && testcases_ac.trim() !== "") {
            // split testcases_ac into into array, each item now has value: <spec name>#<test case name>
            let testcaseIncludingSpecnames = testcases_ac.split(',');
            if (testcaseIncludingSpecnames.length > 0) {
          // this array will hold final test cases
              let testcaseNamesOnly = [];
          // loop thru all item in the array, and grab the test case bame in it
              testcaseIncludingSpecnames.forEach(item => {
                item = item.trim();
                let i = item.indexOf('#');
                if (i > 0) {
                  // extract test case name
                  let testcaseName = item.substring(i + 1).trim();
                  // push test case name to the array
                  testcaseNamesOnly.push(testcaseName);
                }
              });
              // if there are test case names in the arracy, rebuild the execute command to execute them
              if (testcaseNamesOnly.length > 0) {
                testCommand += ' -- --grep="' + testcaseNamesOnly.join('|') + '"';
              }
            }
          }
          execSync(testCommand, {
            cwd: process.cwd(),
            stdio: 'inherit'
          });
        } else {
          console.error('Cannot connect to WebDriver.');
        }
      } catch(error) {
        console.log('Error executing Protractor test: ' + error);
      } finally {
        util.killProcess(childProcesses.pid)
      }
    });
  8. In the Path to Results field, enter the path to the test result folder, relative to the source folder.

    • For Mac or Linux, enter /usr/local/var/protractor-sample/test-results.

    • For Windows, enter D:\protractor-sample\test-results.

  9. In the Result Parser field, select JUnit for Java (built-in).

  10. Click Save to finish creating the agent.

    The qTest Automation Host screen appears.

  11. In the Agents section, click the Run Now button in the Action column for the Protractor Universal Agent.

    The Run Agent window appears.

  12. Click Execute to execute the agent.

    When the execution is finished, the test results will be submitted to qTest.

    Test results will be viewable on the Test Execution tab as test runs under a test suite named "Automation YYYY-MM-DD," where "YYYY-MM-DD" is the date that the execution was run.