Tips for creating a PageObject method that functions similarly to Protractor methods

When using protractor, the following operations are possible:

beforeEach(function() {
  browser.get(myLoginUrl);
  this.username = element(by.model('username'));
  this.password = element(by.model('password'));
  this.loginButton = element(by.css('[ng-click="login()"]'));

  this.username.sendKeys(...);
  this.password.sendKeys(...);
  this.loginButton.click();

  // i'm logged in
});

All of the above methods will execute sequentially without any issues.

I have created a PageObject model to represent my login page for testing other pages. I am currently working on making my PageObject model methods perform similar to protractor methods, running in a 'series'.

During the login process, a session id is generated which is required for subsequent HTTP requests. After logging in, I wish to test the home page by utilizing a Login PageObject:

beforeEach(function() {
  var sessionId = loginPage.loginAs('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="35415046414046504775504d54584559501b565a58">[email protected]</a>', 'mypassword');
  
  homePage = new HomePage(sessionId);
});

it('is accessible', function() {
  homePage.get();
  
  expect(browser.getCurrentUrl()).toMatch(homePage.homePageRegex);
});

I want the line

homePage = new HomePage(sessionId)

to wait until

var sessionId = loginPage.loginAs(...)

has completely executed and returned a valid sessionId, similar to how protractor elements work.

One attempt utilizing promises:

loginPage.loginAs('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f68293858283859384b6938e979b869a93a69693969782bd828e8c">[email protected]</a>', 'mypassword').then(function(sessionId) {
  homePage = new HomePage(sessionId);
});

This approach fails as the beforeEach function completes before setting the sessionId, causing errors during execution.

Experimenting with:

browser.driver.controlFlow().execute(function() {...});

in an attempt to synchronize code execution has not been successful yet.

If anyone knows how to achieve what I'm attempting, please share your insights!

I am aiming to avoid excessive chaining of then() functions as mentioned in the Control Flow section:

https://code.google.com/p/selenium/wiki/WebDriverJs#Understanding_the_API

Answer №1

When working with Protractor, it's important to recognize that many of the methods may not actually execute immediately as they appear to. Instead, they enqueue a promise to carry out the requested action at a later time.

In this scenario, utilizing the then() method is recommended for initializing the HomePage:

loginPage.loginAs('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="15617066616066706755706d74786579703b767a78">[email protected]</a>', 'mypassword').then(function(sessionId) {
  homePage = new HomePage(sessionId);
});

To ensure the subsequent code in the it block waits for the completion of the then function, saving the returned promise from then is necessary. This promise can be used to pass along results, hence naming it as homePage.

var homePage;

...

homePage = loginPage.loginAs('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f68293858283859384b6938e979b869a93">[email protected]</a>', 'mypassword').then(function(sessionId) {
  return new HomePage(sessionId);  // Return the page via the promise
});

Subsequently, you can chain off this promise within your test:

homePage.then(function(page) {
   page.get();

   expect(browser.getCurrentUrl()).toMatch(page.homePageRegex);
});

It's worth noting that incorporating additional actions like accessing the page's "homePageRegex" within the then block should work seamlessly, although there's a slight chance it may not.

Lastly, sharing promises across different blocks like it or beforeEach generally shouldn't pose any special challenges, but always be cautious of potential unforeseen issues.

Answer №2

Have you implemented loginAs to return a promise? If so, you can then use the following code:

beforeEach(function() {
  loginPage.loginAs('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1b6f7e686f6e687e695b7e637a776f76777c">[email protected]</a>', 'mypassword').
     then(function(sessionId) {
       homePage = new HomePage(sessionId);
     });
});

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

Design a search page with expandable fields for a user-friendly experience

Initially, my search page displays 12 fields. I would like to add a link labeled "MORE" that will reveal an additional 10 fields, including the original ones. If the user clicks on "HIDE," these extra 10 fields will disappear as well. ...

How can I access the javascript player using a URL code?

Can someone recommend a universal video player that can play videos from any URL, including YouTube and Vimeo? Thank you in advance! ...

Problem with jQuery AJAX Request Resolving JSON Data

One thing I have on my first page is this function: <script> function update() { $("#notice_div").html('Loading..'); $.ajax({ type: 'GET', dataType: 'json', data: latestid, url: '2includejso ...

I am unable to access the "image" field on the "Query" type in GraphCMS when using Gatsbyjs

Hello there, I'm completely new to Gatsby and Graphql. I've been diving into the CMS system but keep encountering this error that I can't quite figure out. Any guidance would be greatly appreciated. Below is the exact error message I've ...

jQuery's on change event only fires once for database values

In my code, I have three select dropdowns identified by the ids first-choice, second-choice, and third-choice. <select id="first-choice" style="border-radius: 0; width: 100%;" class="form-control" name="area"> <option value="">-Select-&l ...

Tips for moving and saving a file to a specific location before downloading it using Python and Selenium with the Chrome Webdriver

Recently, I started using the Selenium Chrome WebDriver. I have been navigating a webpage where I input my login details and then download a file in CSV format by clicking on a button (the file is saved directly to my downloads folder). However, I would p ...

Prefixes for logging - Consider using the not-singleton technique or another approach

I am currently developing a logging helper for Node.JS that includes several exported functions such as error and warn. For instance, I have two other scripts called test1 and test2 which make use of this "module". When initializing my logging module us ...

In my React.js project, I am looking to iterate through an array of objects and organize them based on a specific condition

Here is an example of the structure of my JSON file: { "PlanetIdentifier": "KOI-1843.03", "TypeFlag": 0, "PlanetaryMassJpt": 0.0014, "RadiusJpt": 0.054, "PeriodDays": 0.176891 ...

Having trouble interacting with a <div> button using Selenium WebDriver

There is a button that I need to click on, but it is actually a <div> tag. Unfortunately, I am having trouble clicking on it. Here is the HTML snippet: <div id="search_product" class="ng-scope" ng-init="init({ searchPath: { simple: '/market ...

Looking for solutions to fix org.openqa.selenium.WebDriverException?

Looking to enhance my automated testing process, I aim to detect and report any bugs directly within the GitHub repository. The specific hurdle I am facing lies with the functionality of the "Submit new issue" button on the GitHub Issue Tracker. See below ...

Steps for making a dynamic number animation

Is there a way to create dynamic number changes when the user stops on a page using HTML, CSS, and JavaScript? I'd like the numbers to change as the user scrolls through the page until they come to a stop. I want the numbers to update quickly while t ...

The JSON data did not fully transfer into my AngularJS application

I wrote the code to display country details, but I am only getting partial information from the JSON. I am only able to fetch the country name and population in the output. Could there be an issue with the syntax? <!DOCTYPE HTML> <html ng-app= ...

Shadow typing, also known as type over words, is a method where the

I am currently tackling a project focused on language acquisition, including German, Chinese, and more. We are encountering difficulties with one specific feature - the ability to display "ghost" text (in a very faint grey) for users to type over. With th ...

Transforming jQuery object into HTML code

I need assistance with a JavaScript task where I am trying to parse and replace an item within an HTML string, but then struggling to convert it back to a string. Specifically, I am having difficulty turning the new jQuery object back to HTML. var compile ...

Malfunction in parsing the post request body

Recently, I have been facing an issue while attempting to execute a $http.post request in this manner: $http({ method: 'POST', url: '//192.168.2.1:3000/auth/signup', data: $scope.credentials, headers: { 'Content- ...

What is the best way to clear an input value in Vuejs after it has been submitted?

Could you help me with my to-do list in Vuejs? I'm having trouble resetting the input value when a new item is added. Any suggestions on how to achieve this? I've attempted to retrieve the input value and set it to an empty string, but unfortuna ...

What is preventing me from accessing my session array in this.state.props from my mapStateToProps in React-Native Redux?

I am currently facing an issue with my Redux store setup. I am attempting to store an array of Session objects, where each Session object contains an array of Hand objects. However, when trying to access my store using `mapStateToProps`, none of the option ...

Is it possible to search a JSON Array using a variable as the criteria

I have a JSON Array that needs to be searched: [ { "Device_ID":"1", "Image":"HTC-One-X.png", "Manufacturer":"HTC", "Model":"One X", "Region":"GSM", "Type":"Phone" }, { "Device_ID":"2", "Image":"Motorol ...

What is the best way to refresh from local storage when using the Ionic Framework?

Having an issue with refreshing data from localStorage. I currently have a list of items that I am able to display. When I add a new item to the array, it shows up properly. Everything seems to be in order as I can see that the new object was added to th ...

Generating an image element on-the-fly using canvas

Hello, I am looking for a way to manipulate a canvas and use a jQuery plugin that needs an img-element input. Is there a method to dynamically generate an img-element from the canvas using JavaScript? ...