wdio-cucumber-framework icon indicating copy to clipboard operation
wdio-cucumber-framework copied to clipboard

`Cannot read property 'ELEMENT' of null` when using page objects in hooks.

Open ringods opened this issue 7 years ago • 8 comments

Context:

  • webdriverio 4.12.0
  • wdio-cucumber-framework 1.1.1 (can't use v2.x because of #112)

Is the browser object fully initialized when running a beforeFeature hook function? I have this in my wdio config file:

  beforeFeature: function (feature) {
    const { loginHook } = require('../steps/handlers')
    loginHook(feature)
  }

The loginHook function is called for every feature to have a logged in application session. The only feature where this hook is not used is the login feature itself. The loginHook function calls into the same PageObject code as the login feature test code. When testing the login feature, it works, but at the hook time not. Error is:

TypeError: Cannot read property 'ELEMENT' of null
    at element("//input[@class="input"]") - index.js:316:3

Looking in the main webdriver.io issue database, this resembles a lot issue https://github.com/webdriverio/webdriverio/issues/1811 where an update of the mocha runner is advised. If I look at the changes in the mocha runner, a function titled waitUntilSettled is added after executing hooks functions:

https://github.com/webdriverio/wdio-mocha-framework/commit/865480b40a9f26731d690d3aaa31b3b0456c4f7a https://github.com/webdriverio/wdio-mocha-framework/commit/e4000cf70c18274811aa7a74b10e0f7bac6b01fe

Any idea?

ringods avatar May 14 '18 12:05 ringods

@ringods can you share loginHook code?

BorisOsipov avatar May 14 '18 13:05 BorisOsipov

Hook function:

export function loginHook (feature) {
  // Skip when we are testing the login functionality
  var hasTagLogin = hasTag(feature, 'name', '@login')
  if (!hasTagLogin) {
    console.log('Logging in before feature ' + feature)
    loginPage.openLogin()
    loginPage.login('username', 'password')
    loginPage.waitForloginPageToLoad()
  }
}

Login PageObject:


class LoginPage {
  get footer () {
    const a = browser.element('//div[@class="footer-banner-container"]')
    return a
  }
  // ... other elements here

  waitForloginPageToLoad () {
    this.footer.waitForExist(5000)
    this.footer.waitForVisible(5000)
  }

  login (username, password) {
    this.waitForloginPageToLoad()
    this.usernameInput.setValue(username)
    this.passwordInput.setValue(password)
    this.loginButton.click()
  }
}

// ... other methods here

export default new LoginPage()

And I repeat: this login pageobject works correctly when I use it during a test of the login feature. When invoking it via the loginHook function during beforeFeature, I get errors.

ringods avatar May 14 '18 13:05 ringods

no ideas. I can make advice to try cucumber hooks - https://github.com/cucumber/cucumber-js/blob/2.x/docs/support_files/hooks.md#tagged-hooks

BorisOsipov avatar May 14 '18 13:05 BorisOsipov

@BorisOsipov I migrated from these hooks to the wdio documented cucumber hooks because I thought that the normal cucumber tagged hooks did not have the "correct" integration.

ringods avatar May 14 '18 13:05 ringods

@ringods can you provide the driver logs?

christian-bromann avatar May 14 '18 13:05 christian-bromann

Not helpful I guess. The only content after a wdio run in file webdriver-log.txt is this:

Starting ChromeDriver 2.37.544337 (8c0344a12e552148c185f7d5117db1f28d6c9e85) on port 4444
Only local connections are allowed.

That's all.

ringods avatar May 14 '18 13:05 ringods

@ringods

Just checking, first of all, did you already fixed this? If not, I was just wondering the following. Where to you open the page, is that also in the LoginPage, because the browser object should already be initialised there, but maybe not with the url.

wswebcreation avatar Jul 26 '18 06:07 wswebcreation

@wswebcreation this is not fixed yet.

The latest code for LoginPage reads this:

import Page from './page';

class Login extends Page {

  ...

  open() {
    super.open('/#login/');
    this.waitForloginPageToLoad();
  }

  ...

Base Page class contains this:

export default class Page {
  open(path) {
    browser.url(path);
  }
}

I still get this error with wdio-cucumber-framework v2.2.1. If you know how to get this fixed, I would be very grateful! 😉

ringods avatar Jul 30 '18 11:07 ringods