Having trouble implementing the page object model with cucumber.js: bug detected!

I have been working on implementing a page object pattern in my cucumber.js test automation suite with selenium webdriver. However, I am facing an error when trying to call the page object from my test step. The folder structure I am using is as follows:

features
|__pages - login_page.js
|__steps - login_steps.js
|__support - world.js

The feature file looks like this:

Feature File

Scenario: Login 
Given I browse to the login page
When I enter the username "test" and password "test"
Then I should be logged in successfully

This is how my login page is structured:

'use strict';

exports.login = function () {
   this.driver.get('https://www.example.com/login');
   this.driver.findElement({ id: 'username' }).sendKeys('my username');
   this.driver.findElement({ id: 'password' }).sendKeys('my password');
   this.driver.findElement({ id: 'btn-login'}).click();
};

And here is my steps definition file:

'use strict';

var expect = require('chai').expect;
var loginpage = require('../pages/LoginPage');


module.exports = function() {
   this.World = require('../support/world.js').World;

   this.Given(/^I enter the username "(.*)", and password (.*)"$/, function (username, password) {
//call page object
    loginpage.login();

    });


};

However, when running the test, I encounter the following error message:

TypeError: Cannot read property 'get' of undefined
      at Object.exports.login (/Users/Gerry/cuke/features/pages/LoginPage.js:9:16)

This error points to the line: this.driver.get('https://www.example.com/login');

The steps within the login function work fine if directly inserted into the steps without calling the page object.

Any suggestions or ideas on what could be going wrong here?

Answer №1

After some troubleshooting, I managed to solve the issue at hand. The main problem was that the context of 'this' in the steps did not align with the context in the page object. To resolve this, I had to pass the current context of 'this' into the page function. Here's how my updated steps now appear:

'use strict';

var expect = require('chai').expect;
var loginpage = require('../../pages/LoginPage');
var World = require('../support/world.js').World;

module.exports = function() {
  this.World = World;
  this.Given(/^I enter the following login credentials "(.*)", and " (.*)"$/, function (username, password) {

    // We need to pass the current context of `this` so we can access
    // the driver in the page function
    loginpage.login(this, username, password);
});

As for the login page function, it has been updated as follows:

'use strict';
exports.login = function (context, username, password) {
   context.driver.get('https://www.getturnstyle.com/login');
   context.driver.findElement({ id: 'username' }).sendKeys(username);
   context.driver.findElement({ id: 'password' }).sendKeys(password);
   context.driver.findElement({ id: 'btn-login'}).click();
};

module.exports = exports;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Navigate to a specific line in Vscode once a new document is opened

Currently, I am working on a project to create a VS Code extension that will allow me to navigate to a specific file:num. However, I have encountered a roadblock when it comes to moving the cursor to a particular line after opening the file. I could use so ...

Which event in the listbox should I trigger to adjust the scroll position?

My webpage includes a listbox inside an update panel. I've managed to capture the scroll position, but now I'm facing difficulty in identifying the right javascript event to call my function for setting the scroll position after the update panel ...

Launching Chrome using a Python script

I am currently developing a Python script to launch the Chrome browser and bypass Cloudflare bot detection (captcha, Java rendering, etc.). However, I have encountered an issue where Chrome is not being launched using the following script: pip install un ...

Act in synchronization

When attempting to run behave tests in parallel, I utilize the behave-parallel library and a sample project from https://github.com/vishalm/behave_parallel_demo. However, my operating system is Windows 10. Following the steps outlined in the Read_me file, ...

The contents of Ionic views are not stored in a cache, so the controller must

In my ionic application, I have several views. When I launch the app, it takes me to the main view where data is loaded upon initialization of the controller. The issue arises when I navigate away from this view using tabs; sometimes the controller gets d ...

Customize the appearance of radio buttons in HTML by removing the bullets

Is there a way for a specific form component to function as radio buttons, with only one option selectable at a time, without displaying the actual radio bullets? I am looking for alternative presentation methods like highlighting the selected option or ...

Guide on managing firebase and webrtc tasks within a client-side component using Next.js 13

I developed a Next.js 13 application to share the camera feed using WebRTC and Firestore. Below is my page.tsx file where I am facing some challenges. I can't make this server-side because I'm using React hooks, and moving it to the client side i ...

Unable to update data from false to true in vue.js

What I'm trying to do is change the data from false to true in order to conditionally render a button when a payment has succeeded. When making an axios call, I receive 'succeeded' as the response in the JSON object and can log it to the con ...

Identifying when a class is added to an element using Protractor and Web Driver

Here is the snippet of code for a button that changes color to blue when clicked: <button id="testbutton" type="button" ng-class="selected('test')" ng-click="isMultiple('test')">test</button> When viewing in the browser, t ...

issues with jquery functionality on user control page

For searching through dropdown lists in my project, I have implemented the Chosen jQuery plugin. In the Master page before the closing body tag, ensure to include the necessary CSS and jQuery script files. <link href="/assets/css/chosen.css" rel=" ...

Can a node.js file be exported with a class that includes IPC hooks?

[Node.js v8.10.0] To keep things simple, let's break down this example into three scripts: parent.js, first.js, and second.js parent.js: 'use strict'; const path = require('path'); const {fork} = require('child_process&apo ...

Does the method in the superclass "not exist" within this type....?

Our TS application utilizes a JavaScript library, for which we crafted a .d.ts file to integrate it with TypeScript. Initially, the file resided in a "typings" directory within the project and everything operated smoothly. Subsequently, we opted to relocat ...

Retrieve the data from every dropdown menu

How can I retrieve the selected values from all created selects when a button is clicked? I have attempted using both refs and v-model, but neither of them are functioning as expected. <div v-for="attribute in attributes" class="col"> {{ a ...

JavaScript Scrolling Functionality Not Functioning as Expected

I have implemented a scroll function on my website $('#lisr').scroll( function() { if($(this).scrollTop() + $(this).innerHeight()>= $(this)[0].scrollHeight) { //Perform some action here } } However, I am encountering an ...

Can someone explain the purpose of the sel.open('/') statement in this code snippet?

What is the purpose of using the sel.open('/') command? sel = selenium('localhost', 4444, '*firefox', 'http://www.google.com/') sel.start() sel.open('/') sel.wait_for_page_to_load(10000) sel.stop() Could ...

Switch between showing and hiding a div by clicking on the panel header and changing the symbol from + to

I need assistance with a panel feature on my website. The panel should expand when the "+" symbol is clicked, displaying the panel body, and the "+" symbol should change to "-" indicating it can be collapsed by clicking it again. There is a slight twist t ...

Properly handling curves in THREE.JS to ensure efficient disposal

I am facing a challenge with managing memory in my project. I have a dynamic sphere with moving points on it, and I am creating curves to connect these points. Here is an illustration of the process: https://i.sstatic.net/PGWuU.jpg As the points are cons ...

Is there a substitute for AngularJS $watch in Aurelia?

I'm in the process of transitioning my existing Angular.js project to Aurelia.js. Here is an example of what I am trying to accomplish: report.js export class Report { list = []; //TODO listChanged(newList, oldList){ ...

leveraging a Nuxt plugin and saving it in middleware

My goal is to create a middleware that validates the authentication and entitlement of users. The authentication details are retrieved from my store: //store/index.js const state = () => ({ auth: { isLoggedIn: false // more properties here } ...

Is there a way to implement jwt.verify() from jsonwebtoken in a React application?

Every time I attempt to use the jwt.verify() or jwt.decode() function in my React project, it keeps throwing a multitude of errors. The errors that I encounter are: ERROR in ./node_modules/jwa/index.js 5:13-30 Module not found: Error: Can't resolve ...