首页 > 解决方案 > Test failing only in headless chrome

问题描述

I have some integration tests using wdio, they are all passing. However, when I run them in headless chrome, one of these tests fails. I get this error:

1) Reset password by submitting a new password "before all" hook:

element ("#identifierNext") still not existing after 15000ms

The problem is in this line of code:

browser.waitForExist('#identifierNext');

Which is weird, because I am using the waitForExist(<element id>) in other tests as well and they pass even in headless chrome. I also tried to increase the waitFor limit up to 30000ms, but it fails anyway.

This is my wdio config:

exports.config = {
    specs: [
        './test/pageobjects/**/reset_password.spec.js'
    ],
    maxInstances: 1,
    capabilities: [{
        maxInstances: 1,
        browserName: 'chrome',
        'goog:chromeOptions': {
            args: ['--headless', '--disable-gpu', '--window-size=1280,800', '--no-sandbox', '--disable-dev-shm-usage']
        }
    }],
    sync: true,
    logLevel: 'silent',
    coloredLogs: true,
    deprecationWarnings: true,
    bail: 0,
    screenshotPath: './errorShots/',
    baseUrl: 'http://127.0.0.1:3000',
    waitforTimeout: 10000,
    connectionRetryTimeout: 90000,
    connectionRetryCount: 3,
    services: ['selenium-standalone'],
    framework: 'mocha',
    reporters: ['spec'],
    mochaOpts: {
        ui: 'bdd',
        timeout: 30000
    },
}

When I remove headless from chromeOptions, this test passes normally. Any ideas why this happens?

EDIT: this is my reset_password.spec.js file:

describe ('Reset password by submitting a new password', function(){
  //test fails in this before function
  before(function(){
    browser.url(ResetPassword.token_url(valid_email, email_password));
  });

  it ('Password reset without passwords', function(){
    .
    .
    .
  })

});

And my reset_password.page.js file:

const Page = require('./page');

class ResetPassword extends Page {

  get email() {
    return $('input[type="text"]');
  }

  get url() {
    return browser.getUrl();
  }

  open() {
    super.open('/reset-password');
  }

  get signIn(){
    browser.waitForExist('*=Sign in');
    return $('*=Sign in');
  }

  get enterEmail(){
    browser.waitForExist('input[type="email"]');
    return $('input[type="email"]');
  }

  get submitEmail(){
    //this fails in headless mode
    browser.waitForExist('#identifierNext');
    return $('#identifierNext');
  }

  get enterPassword(){
    browser.waitForExist('#password > div.aCsJod.oJeWuf > div > div.Xb9hP > input');
    return $('#password > div.aCsJod.oJeWuf > div > div.Xb9hP > input');
  }

  get submitPassword(){
    browser.waitForExist('#passwordNext');
    return $('#passwordNext');
  }

  get tokenEmail(){
    browser.waitForExist('span[email="profiq.ldap@gmail.com"]');
    return $$('span[email="profiq.ldap@gmail.com"]');
  }

  get tokenURL(){
    browser.waitForExist('a[id*=reset_link]');
    const links = $$('a[id*=reset_link]');
    return links[links.length-1].getAttribute('href');
  }

  token_url(email, password){
    browser.url('https://www.google.com/gmail/about/#');
    this.signIn.click();
    browser.switchTab(browser.getTabIds()[1]);
    this.enterEmail.setValue(email);
    this.submitEmail.click();
    this.enterPassword.setValue(password);
    this.submitPassword.click();
    this.tokenEmail[1].click();
    browser.pause(3000);
    return this.tokenURL;
  }

}

module.exports = ResetPassword;

标签: javascriptintegration-testingheadlesswdio-v4

解决方案


我发现了问题。Gmail 在不同浏览器中的显示方式不同。我browser.saveScreenshot('screenshot.jpg');在测试失败之前使用了一个屏幕截图,它显示页面看起来不同(使用我的本地语言而不是英语,并且具有不同的外观和按钮)。所以这就是为什么测试找不到具有给定标识符的按钮的原因。


推荐阅读