`Cannot read property 'ELEMENT' of null` when using page objects in hooks.
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 can you share loginHook code?
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.
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 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 can you provide the driver logs?
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
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 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! 😉