admin管理员组

文章数量:1432446

The Problem:

In our rather big test codebase, we are using different keyboard shortcuts. For instance, to copy selected text we are using CTRL/COMMAND + C, to paste CTRL/COMMAND + v, to open a new tab CTRL/COMMAND + T etc.

To keep tests work on multiple platforms, we'd like to make the CTRL vs COMMAND choice automatic depending on what platform the target browser is running on. To determine a target platform, we are currently using the following helper function which uses navigator.appVersion:

this.getControlKey = function () {
    return browser.executeScript("return navigator.appVersion.indexOf('Mac');").then(function (isMac) {
        return isMac ? protractor.Key.COMMAND : protractor.Key.CONTROL;
    });
};

The problem with this approach is that getControlKey() returns a promise and, every time we use it, we have to resolve the promise explicitly:

helpers.getControlKey().then(function (controlKey) {
    elm.sendKeys(protractor.Key.chord(controlKey, "c"));
});

The Question(s):

  1. Is it possible to avoid the nestedness and simplify the use of getControlKey()? Ideally I would like it work as simple as:

    elm.sendKeys(protractor.Key.chord(helpers.getControlKey(), "c"));
    
  2. Is using navigator.appVersion the best approach to determine a target platform, and is there a better way?

The Problem:

In our rather big test codebase, we are using different keyboard shortcuts. For instance, to copy selected text we are using CTRL/COMMAND + C, to paste CTRL/COMMAND + v, to open a new tab CTRL/COMMAND + T etc.

To keep tests work on multiple platforms, we'd like to make the CTRL vs COMMAND choice automatic depending on what platform the target browser is running on. To determine a target platform, we are currently using the following helper function which uses navigator.appVersion:

this.getControlKey = function () {
    return browser.executeScript("return navigator.appVersion.indexOf('Mac');").then(function (isMac) {
        return isMac ? protractor.Key.COMMAND : protractor.Key.CONTROL;
    });
};

The problem with this approach is that getControlKey() returns a promise and, every time we use it, we have to resolve the promise explicitly:

helpers.getControlKey().then(function (controlKey) {
    elm.sendKeys(protractor.Key.chord(controlKey, "c"));
});

The Question(s):

  1. Is it possible to avoid the nestedness and simplify the use of getControlKey()? Ideally I would like it work as simple as:

    elm.sendKeys(protractor.Key.chord(helpers.getControlKey(), "c"));
    
  2. Is using navigator.appVersion the best approach to determine a target platform, and is there a better way?

Share Improve this question asked Oct 21, 2015 at 15:16 alecxealecxe 475k127 gold badges1.1k silver badges1.2k bronze badges 5
  • As Protractor runs in Node.js env I think you can use os.platform(), which is a synchronous call (assuming that tests are being executed on the same machine with the browser). – Michael Radionov Commented Oct 21, 2015 at 15:39
  • 1 @MichaelRadionov the problem is, we cannot assume the machine where tests are executed is the same machine where the browser is started up. Thanks. – alecxe Commented Oct 21, 2015 at 15:49
  • 1 This isn't a clean solution, but you could just do your navigator lookup in onPrepare once and define a constant/helper there. That would avoid the need to pass around a promise. – Nick Tomlin Commented Oct 21, 2015 at 17:43
  • 1 A question, when you say the platform should be automatically chosen, does it mean that you are running your tests on a selenium grid kind of environment? Or is it that all the tests run on one platform and tests are not distributed and whenever they run, platform should automatically be chosen? Thanks – giri-sh Commented Oct 21, 2015 at 18:01
  • 1 @GirishSortur good question. Well, two things here. First of all, we have multiple testers in the team and we all use different platforms. Plus, yes, we have a separate protractor config for tests on a browserstack on a wide range of browsers+platforms. Thanks. – alecxe Commented Oct 21, 2015 at 18:04
Add a ment  | 

1 Answer 1

Reset to default 5 +50

Here's my best to answer your first question, for the two scenarios -

  • If multiple testers run the scripts in their own machine, the helper method can be placed in onPrepare() function assigning the value to a constant global variable, which will be available for all the tests.

  • If all the tests are run on a distributed platform where all tests are randomly assigned to different machines, in that case writing the helper method assigning the value to a constant local variable for that test in beforeAll() function will be useful.

Moving to your second question, there is also another way where we can get the platform on which the test spec is being executed using protractor's getCapabilities() method.

Code for getting the platform type -

//Below code can be placed either in `onPrepare()` function or `beforeAll()` function depending the need.
//If the below code is placed in the `beforeAll()` function then i guess there won't be any need for a global variable.

browser.controlKey = protractor.Key.CONTROL; //browser.controlKey is a global variable and can be accessed anywhere in the test specs
browser.getCapabilities().then(function(capabilities){
    if(capabilities.caps_.platform === "MAC")
        browser.controlKey = protractor.Key.COMMAND;
});

Usage:

elm.sendKeys(protractor.Key.chord(browser.controlKey, "c")); //if its stored as global variable

Hope it helps.

本文标签: javascriptUsing crossplatform keyboard shortcuts in endtoend testingStack Overflow