E2E Testing - WebdriverJS, Selenium and Jasmine

2019-07-24 03:21发布

问题:

OK so I have followed several slightly differing examples, as you can see in my commented code below. They all claim to work, but I cannot get it to do so.

I'm using; - selenium-webdriver - jasmine-node-reporter-fix (jasmine-node errors)

So its quite a simple asynchronous test, opening Google and searching, then getting the page title.

Problem; The page title returned is the Google homepage and not the search results page. (Browser ends up on the search results page).

Code

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
    withCapabilities(webdriver.Capabilities.firefox()).
    build();

jasmine.DEFAULT_TIMEOUT_INTERVAL = 9999999;

describe('basic test', function () {

    it('should be on correct page', function (done) {
        //driver.get('http://www.wingify.com');
        //driver.getTitle().then(function (title) {
        //  expect(title).toBe('Wingify');
        //  // Jasmine waits for the done callback to be called before proceeding to next specification.
        //  done();
        //});


        driver.get("http://www.google.com");
        driver.findElement(webdriver.By.name("q")).sendKeys("webdriver");
        driver.findElement(webdriver.By.name("btnG")).click();
        //driver.getTitle().then(function (title) {
        //  console.log(title);
        //  console.log(expect);
        //  expect(title).toBe('webdriver - Google Search');
        //  done();
        //});
        driver.wait(function () {
            driver.getTitle().then(function (title) {
                expect(title).toBe('webdriver - Google Search');
                done();
            });
        }, 5000);

    });
});

Result

Failures:

  1) basic test should be on correct page
   Message:
     Expected 'Google' to be 'webdriver - Google Search'.
   Stacktrace:
     Error: Expected 'Google' to be 'webdriver - Google Search'.
    at C:\Stash\Will-Hancock\grunt-jasmine\spec\test-spec.js:31:19
    at C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\goog\base.js:1243:15
    at webdriver.promise.ControlFlow.runInNewFrame_ (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:1539
:20)
    at notify (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:362:12)
    at notifyAll (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:331:7)
    at resolve (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:309:7)
    at fulfill (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:429:5)
    at Object.webdriver.promise.asap (C:\Stash\Will-Hancock\grunt-jasmine\node_modules\selenium-webdriver\lib\webdriver\promise.js:671:5)

Finished in 4.281 seconds
1 test, 1 assertion, 1 failure, 0 skipped

So some people have said I need the jasmine timeout extended, this makes no difference.

Others saying you need the Jasmine done() method - without this the test doesn't complete.

I cannot see why the wait doesn't wait! - the result is returned immediately whatever the timeout provided.

回答1:

See this answer - "The inner function will return a promise that driver.wait will wait for and will take its value (true/false) as the waiting condition"

The change you should apply is -

driver.wait(function () {
            return driver.getTitle().then(function (title) {
                return title === 'webdriver - Google Search';
            });
        }, 5000);


回答2:

So, the problem with the above was that I could not get Jasmine to wait for the page load before doing the assertion, using driver.wait.

Jasmine was completing before driver.wait returned.

Instead I used Jasmine's waitsFor() method.

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
    withCapabilities(webdriver.Capabilities.chrome()).
    build();

describe('basic test', function () {

    it('should be on correct page', function () {
        var match = 'webdriver - Google Search',
            title = '';

        driver.get("http://www.google.com");
        driver.findElement(webdriver.By.name("q")).sendKeys("webdriver");
        driver.findElement(webdriver.By.name("btnG")).click();

        // wait for page title, we know we are there
        waitsFor(function () {
            driver.getTitle().then(function (_title) {
                title = _title;
            });
            return title === match;
        }, 'Test page title, so we know page is loaded', 6000);

        // test title is correct
        runs(function () {
            expect(title).toEqual(match);
        });
    });
});


回答3:

Like you said in your own answer, the problem was that you weren't waiting for the page to load. I really don't like the method name for driver.wait, because it implies that it will wait the specified amount of time before continuing, but that's not the case. It's only a timeout if your promise does not resolve. To wait, you should use driver.sleep(1000). Then you can add your expectations, like so:

driver.sleep(1000).then(function () {
   return driver.getTitle().then(function (title) {
       expect(title).toBe('webdriver - Google Search');
       done();
   });
});

(Since you were using done in your question, I'm assuming Jasmine 2.0 and done)

Hope this helps.