How can I utilize PageFactory with Selenium WebdriverJS?

I am currently transitioning to writing my tests in TypeScript (using JavaScript is also an option) and struggling with understanding how to implement the PageFactory concept from C#. In C#, I typically create separate classes for each page or form on the website that I am testing. For example:

public class RegisterForm
{
    public RegisterForm()
    {
        PageFactory.InitElements(Driver.Chrome, this);
    }

    [FindsBy(How = How.CssSelector, Using = @"........")]
    public IWebElement EmailField { get; set; }
}

Whenever I needed to interact with elements from the RegisterForm, I would initialize this class and access them from there. How can I achieve something similar in TypeScript or JavaScript?

Answer №1

Here is an example of how I implemented my page objects in Protractor for a non-angular page:

'use strict';

var DocumentationPage = function () {

    var documentationLink = element(by.css(".nav-global a[href*='Docs'"));
    var documentationURL = "https://docs.docker.com/"
    var installButton = element(by.buttonText("Install"));
    var dockerEngineButton = element(by.buttonText("Docker Engine"));
    var dockerLinuxButton = element(by.buttonText("Linux"));
    var dockerCloudButton = element(by.buttonText("Cloud"));
    var dockerFundamentalsButton = element(by.buttonText("Docker Fundamentals"));
    var useDockerButton = element(by.buttonText("Use Docker"));
    var amazonInstallLink = element(by.partialLinkText("Amazon EC2 Installation"));


    this.go = function(){
        browser.get(documentationURL);
        browser.sleep(100);
    };
    this.drillDownToAmazonInstallDocumentation = function(){
        installButton.click();
        browser.sleep(100);
        dockerEngineButton.click();
        browser.sleep(100);
        dockerCloudButton.click();
        browser.sleep(100);
    };
    this.clickInstallOnAmazonLink = function(){
        amazonInstallLink.click();
        browser.sleep(100);
    };
   this.drillUpToAmazonInstallDocumentation = function(){
        dockerCloudButton.click();
        browser.sleep(100);
        dockerEngineButton.click();
        browser.sleep(100);
        installButton.click();
        browser.sleep(2000);
    };
};

module.exports = DocumentationPage;

In my tests, I utilized the page objects as shown below.

var HomePage = require("./pages/HomePage.js");
var DocumentationPage = require('./pages/DocumentationPage.js');


describe("Testing the Docker Documentation UI", function(){

  var hp = new HomePage();
  var dp = new DocumentationPage();

 beforeEach(function(){
   browser.ignoreSynchronization = true;
   dp.go();
 });

  it("Validate accordion navigation drills down", function(){
    dp.drillDownToAmazonInstallDocumentation();
    dp.clickInstallOnAmazonLink();
    expect(browser.getTitle()).toContain("Amazon EC2 Installation");
  });

  it("Validate accordion navigation drills up", function(){
    dp.drillDownToAmazonInstallDocumentation();
    dp.drillUpToAmazonInstallDocumentation();
  });
});

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

Challenging Trigonometry Puzzles in Javascript

In my project, I am creating an interactive application where a group of humans and bacteria engage in a game of chase. However, I encountered a problem where instead of moving directly towards their target, all entities would veer to the left. I attempt ...

Exploring Angular Testing with SpyOn

Apologies for my inexperience with Angular, but I am struggling with using spyOn in a unit test. In my unit test, there is a method on the component that calls service1, which in turn calls another service2. However, when I try to spyOn service1 in order ...

Ensure that text is aligned alongside an image only when both elements are enclosed within <p> tags

When using an API to pull markdown content from Contentful and converting it to HTML with ReactMarkdown, a common issue arises. The resulting HTML structure often places the text content in separate paragraphs such as: <p>Some text content</p> ...

Uploading data through AJAX without saving it in the database

Can someone please assist me? I am encountering an issue where I am uploading multiple data using an AJAX request. The data appears to upload successfully as I receive a response of 200 OK, but for some reason, the data is not being stored in the database. ...

AngularJS display element within viewport

My div is extremely wide and contains many elements. I need a way to bring specific elements into view when a button is clicked. Is there an alternative to $anchorscroll that can achieve this? Looking for a solution for horizontally scrolling to a particu ...

Unable to modify the content of a table cell after triggering a Bootstrap modal event

Looking to update values in rows of a table? Here is an example table: https://i.sstatic.net/6l4f3.png I need to update the title per selected row. After selecting the first row, changing the value works fine. However, when I choose the second row, the ...

Exploring the wonders of Mocha testing for TypeScript with globally defined types

I am in the process of creating a test framework for an older application that includes numerous types.ts files defining types without any imports or exports at the top level. For instance, we have a Pills/types.ts file that solely consists of interface Pi ...

Modifying CSS files in real-time

I've been attempting to dynamically change the CSS file, but I've run into an issue: Whenever I try to alter the style, it seems to work correctly while in "debug mode", showing that the changes are applied. However, once the JavaScript function ...

Error TS2305: The module "@prisma/client" does not have an export named "User"

Setting up a Gitlab CI for my nestjs project using prisma has been my current challenge. I keep encountering this error when running the pipeline: see image here This is what my .gitlab-ci.yml looks like: image: node:latest stages: - build build: st ...

How can you write a parameterless function in Ramda using a point-free style?

Take a look at this functioning code snippet: var randNum = x => () => Math.floor(x*Math.random()); var random10 = randNum(10) times(random10, 10) // => [6, 3, 7, 0, 9, 1, 7, 2, 6, 0] The function randNum creates a random number generator that wi ...

Addressing the problem of reference issues when incorporating debounce functionality with window resize event handling

Currently, I am utilizing react along with lodash's debounce method. The main issue I am facing is regarding the state update when a user resizes the window. The problem arises because this points to the window rather than the component itself when t ...

Tips for accurately inputting a Record key in typescript

Within my code, I have a function that filters the properties of an object based on a specified filtering function: function filterProps<K extends string, V>(object: Record<K, V>, fn: (key:K, value: V, object: Record<K, V>) => unknown) ...

Having trouble with getting v-cloak to function properly when dealing with asynchronous requests

I wanted to explore using the v-cloak directive to showcase a loading spinner while certain data properties in vue js are being loaded asynchronously for me to integrate into a table component. After successfully applying and styling my v-cloak styles on ...

Mastering the art of writing protractor scenarios

In a hypothetical scenario where an Angular app consists of two pages - one for contacts (featuring a table with contacts and an "add new contact" button) and another for adding a new contact, the following steps can be outlined: Click on the "add" butto ...

The error message "MongoDB encountered an issue with accessing the property 'push', as it was undefined."

Exploring node.js, express and MongoDB is a learning journey for me. While working on data association in MongoDB models, I encountered a runtime error. Even though the reference has been added to the model, the push() method fails to recognize it. Here ar ...

Angular route fails to load the HTML file

In the process of developing a route within an Angular application, I have successfully implemented 3 routes. However, one particular route is giving me trouble. I have three folders that need to redirect HTML based on the option chosen. In Angular, I cre ...

Exploring the process of navigating through jQuery Arrays: Utilizing JQuery Array Filter

I need help finding a way to SEARCH through a jQuery array or object. I'm not looking to just check if the value is in the array, but to search for related terms based on user input. It's similar to how we filter ArrayList in Java or use SQL LIKE ...

Tips for submitting a form using a button located outside of a form tag dynamically

I've created a multi-step form with a "next" button to navigate through different steps. On the final page, it transitions to a "submit" button that connects to a form. For this transition, I dynamically set the type and form attributes on the button ...

Incorporating telepat-io into a Java Struts enterprise solution

Our J2EE enterprise application, built on Java Struts, has a static front end. Our team's architect has opted to enhance the user authentication by incorporating Ajax and JavaScript functionalities using telepat-io. The project is currently managed w ...

The operation was computed twice

Below is an example: test.html <!DOCTYPE html> <html ng-app ng-controller="AppController"> <head> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript" src="script1 ...