麻烦,javascript,量角器和类

时间:2016-05-17 15:52:40

标签: javascript node.js protractor

我在理解课程范围以及如何在我所拥有的系统中使用对象,原型等方面遇到了一些麻烦。在我看来,我正确地做事,但它不起作用,我希望有人可以向我解释或让我指出正确的方向。

所以情况如下: 我正在尝试创建一个通用页面对象和验证对象,它将处理带有相关文本标签的输入框。如果我在与页面对象结构相同的类中进行验证,那么事情似乎确实有效,但我最近才知道这是糟糕的设计。

这是一个Angular 2 rc1网站。我使用量角器3.3.0并通过使用webdriver-manager确保了selenium和chromedriver的项目版本是最新的。

所以这就是我所做的(文件名在每个部分开头的评论中):

'use strict';

/*
 * InputLabelPageObject.js
 *
 * This object will provide basic methods for an Input box with an attached label.
 * It is expected that the label will have an element called "label" and an element called "input"
 */

module.exports = InputLabelPageObject;

/**
 * Create an object that will provide methods for an input/label combination of elements.
 *
 * @param container The selector for the __container of the input/label combination of elements.
 */
function InputLabelPageObject(container) {
    this.Container = container;
}

InputLabelPageObject.prototype = {
    constructor: InputLabelPageObject,
    /**
     * Return the element for the label of the input/label combination of elements.
     *
     * @returns {protractor.element}
     */
    getLabel: function () {
        return this.Container.$('label');
    },
    /**
     * Return the element for the input of the input/label combination of elements.
     *
     * @returns {ElementFinder}
     */
    getInput: function () {
        return this.Container.$('input');
    },
    /**
     * Return the text shown in the input of the input/label combination of elements.
     *
     * @returns {Promise}
     */
    getValue: function () {
        return this.getInput().getAttribute('value');
    },
    /**
     * Get the placeholder text shown in the input of the input/label combination of elements.
     *
     * @returns {Promise}
     */
    getPlaceholder: function () {
        return this.getInput().getAttribute('placeholder');
    },
    /**
     * Clears the input element then puts the text from data into the input element.
     *
     * @param data The text to be entered into the input element.
     */
    sendKeys: function (data) {
        var el = this.getInput();
        el.clear().then(function () {
            return el.sendKeys(data);
        });
    }
};

-

'use strict';

/*
 * InputLabelVerification.js
 *
 * Provide verification methods associated with an Input and Label 
 * combination of elements.
 */

module.exports = InputLabelVerifications;

var inputLabelPageObject;

function InputLabelVerifications(inputLabelPageObject) {
    this.__setPageObject(inputLabelPageObject);
}

InputLabelVerifications.prototype = {
    constructor: InputLabelVerifications,
    __setPageObject: function (ilpo) {
        inputLabelPageObject = ilpo;
    },
    /**
     * Verify the text on the label of the input/label combination of elements.
     *
     * @param expected The expected text on the label.
     */
    verifyText: function (expected) {
        //console.log('Asserting text [' + expected + ']');
        expect(inputLabelPageObject.getLabel()).toEqual(expected);
    },
    /**
     * Verify the text shown in the input of the input/label combination of elements.
     *
     * @param expected The expected text in the input element.
     */
    verifyValue: function (expected) {
        //console.log('Asserting input value [' + expected + ']');
        expect(inputLabelPageObject.getValue()).toEqual(expected);
    },
    /**
     * Verify the placeholder text shown in the input of the input/label combination of elements.
     *
     * @param expected The expected text of the placeholder.
     */
    verifyPlaceholder: function (expected) {
        //console.log('Verifying placeholder text [' + expected + ']');
        expect(inputLabelPageObject.getPlaceholder()).toEqual(expected);
    }
};

-

'use strict';

/*
 * LoginPageObject.js
 *
 */

var InputLabelPageObject = require('./generics/InputLabelPageObject.js');

module.exports = LoginPageObject;

var __container = $('login-component');
var username = new InputLabelPageObject(__container.$('form:nth-child(2) > div:nth-child(1)'));
var password = new InputLabelPageObject(__container.$('form:nth-child(2) > div:nth-child(2)'));

/**
 * Create an object that contains the methods necessary to perform actions against the LoginPageObject page.
 *
 * @param url The base URL string. If not undefined, it will load the url+'/login' page.
 * @constructor new LoginPageObject('http://localhost:9000');
 */
function LoginPageObject(url) {
    if (url) {
        this.loadPage(url)
    }
}

LoginPageObject.prototype = {
    constructor: LoginPageObject,
    loadPage: function (url) {
        url = url + '/login';
        console.log('Loading page: '+ url);
        browser.get(url);
    },
    welcome: {
        /**
         * Return the element for the Welcome text
         *
         * @returns {ElementFinder}
         */
        get: function () {
            return __container.$('section:first-child h1:first-child');
        },
    },
    /**
     * Return an InputLabelPageObject object specific for the username input and label elements.
     */
    username: username,
    /**
     * Return an InputLabelPageObject object specific for the password input and label elements.
     */
    password: password,
    loginButton: {
        /**
         * Return the element for the login button.
         *
         * @returns {ElementFinder}
         */
        get: function () {
            return __container.$('form > button');
        },
        /**
         * Click the LoginPageObject button.
         * @returns {*|void|webdriver.promise.Promise<void>|ActionSequence|!webdriver.promise.Promise.<void>}
         */
        click: function () {
            return this.get().click();
        }
    }
};

-

'use strict';

/*
 * LoginPageVerifications.js
 */

var LoginPageObject = require('../pageObjects/LoginPageObject');
var verifyText = require('./generics/VerifyText');
var inputLabelVerifications = require('./generics/InputLabelVerifications');

module.exports = LoginPageVerifications;

var __loginPageObject = new LoginPageObject();

function LoginPageVerifications(url) {
    if (url) {
        __loginPageObject = new LoginPageObject(url);
    }
}

LoginPageVerifications.prototype = {
    constructor: LoginPageVerifications,
    loginPageObject: new LoginPageObject(),
    welcome: {
        verifyText: function (expected) {
            verifyText(__loginPageObject.welcome.get(), expected);
        }
    },
    username: new inputLabelVerifications(__loginPageObject.username),
    password: new inputLabelVerifications(__loginPageObject.password),
    loginButton: {
        verifyText: function (expected) {
            verifyText(__loginPageObject.loginButton.get(), expected);
        }
    },
    /**
     * Performs the actions of logging in. That is, enter the username and password values,
     * then click the LoginPageObject button. This does *not* verify page load.
     *
     * @param username The username to login with.
     * @param password The password to login with.
     */
    doLogin: function (username, password) {
        var uPromise = __loginPageObject.username.sendKeys(username);
        var pPromise = __loginPageObject.password.sendKeys(password);
        protractor.promise.asap(this.username.verifyValue(username));
        protractor.promise.asap(this.password.verifyValue(password));
        protractor.promise.all([uPromise, pPromise]).then(this.loginButton.click());
    },
    /**
     * Verifies all page elements' text or other default attributes.
     *
     * @param welcomeText The expected Welcome text
     * @param userText The expected username label text.
     * @param userPlaceholder The expected username's input element's placeholder text.
     * @param passText The expected password label text.
     * @param passPlaceholder The expected password's input element's placeholder text.
     * @param loginText The expected login button text.
     */
    verifyPage: function (welcomeText, userText, userPlaceholder, passText, passPlaceholder, loginText) {
        this.welcome.verifyText(welcomeText);
        this.username.verifyText(userText);
        this.username.verifyPlaceholder(userPlaceholder);
        this.password.verifyText(passText);
        this.password.verifyPlaceholder(passPlaceholder);
        this.loginButton.verifyText(loginText);
    }

};

-

'use strict';

/*
 * login-spec.js
 */

var LoginPageVerifications = require('../components/actions/LoginPageVerifications');

var myUrl = 'http://localhost:3000';

describe('My Login Page test', function() {
   var loginPage;
   beforeAll(function() {
       loginPage = new LoginPageVerifications(myUrl);
   });

   it('should verify username input and label values', function() {
       var welcomeText = 'Thank you for visiting my login page';
       var userText = 'Username';
       var userPlaceholder = 'Enter your username';
       var passText = 'Password';
       var passPlaceholder = 'Enter your password';
       var loginText = 'Login';

       loginPage.username.verifyText(userText);
       // loginPage.verifyPage(welcomeText, userText, userPlaceholder, passText, passPlaceholder, loginText);
   });
});

我经常看到的结果: 如果在InputLabelVerification.js中我遗漏var inputLabelPageObject或尝试仅在构造函数中设置值,我得到Failed: Cannot read property 'getLabel' of undefined。所以,我发现我必须按照上面显示的方式设置它。

我最接近的是当我收到以下回复时:

A Jasmine spec timed out. Resetting the WebDriver Control Flow.
F

Failures:
1) My Login Page test should verify username input and label values
Expected ({ ptor_: ({ controlFlow: Function, schedule: Function, 
setFileDetector: Function, getSession: Function, getCapabilities: Function, 
quit: Function, actions: Function, touchActions: Function, 
executeScript: Function, executeAsyncScript: Function, call: Function, 
wait: Function, sleep: Function, getWindowHandle... }) }) to equal 'Username'.

在LoginPageVerification.js中,我已经测试并确保其他验证(welcome和loginButton)正常工作。

另外,如果从login-spec.js我添加这一行:

expect(loginPage.loginPageObject.username.getLabel().getText()).toEqual(userText);

这种期望通过了测试。

1 个答案:

答案 0 :(得分:0)

我得到了答案。而现在我觉得很傻。我会在2天内发布答案。 (这只花了我几天的时间才能做到。)

基本上,我从.getLabel() InputLabelPageObject拨打InputLabelVerificationsElementFinder返回getText: function() { this.getLabel().getText(); } ... 返回需要的字符串。 (糟糕)

在InputLabelPageObject中,我添加了以下行:

InputLabelVerifications

然后在verifyText: function (expected) { //console.log('Asserting text [' + expected + ']'); expect(inputLabelPageObject.getText()).toEqual(expected); }, 类中调用该函数,

{
    "variables": {
        "root_password": "pass",
        "output_directory": "output/centos6-aufs-master-slave-vmw"
    },
    "builders": [
        {
            "type": "vmware-iso",
            "name": "centos6-aufs-master-slave-vmw",

            "iso_url": "http://myrepo/software/isos/CentOS-6.5-x86_64-minimal.iso",
            "iso_checksum": "ee3c7e96ad0a33d8af787acbf6d54e56",
            "iso_checksum_type": "md5",

            "ssh_username": "root",
            "ssh_password": "{{user `root_password`}}",
            "ssh_port": 22,
            "ssh_wait_timeout": "10000s",

            "shutdown_command": "shutdown -P now",
            "boot_command": [
                "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/al-master-slave-ks.cfg<enter><wait>"
            ],

            "boot_wait": "10s",

            "disk_size": 51200,
            "disk_type_id": "0",

            "format": "ovf",

            "guest_os_type": "rhel6-64",
            "tools_upload_flavor": "linux",

            "http_directory": "http",

            "output_directory": "{{user `output_directory`}}",

            "vmx_data": {
                "memsize": "2048",
                "numvcpus": "1",
                "cpuid.coresPerSocket": "1"
            }
        }
    ],
    "post-processors": [
        {
            "type": "shell-local",
            "only": ["centos6-aufs-master-slave"],
            "inline": ["cd scripts","./vmx-to-ova.sh"],
            "environment_vars": ["PACKER_OUTPUT_DIRECTORY=/home/myuser/projects/IT/packer-project/output/centos6-aufs-master-slave-vmw"]
        }
    ]
}

并且一切正常。