Tips for ensuring a function is called during testing with Selenium WebDriver and Jest

I have developed an application using Ext JS and am currently creating tests for it using Selenium WebDriver (using the Node package - version 4.0.0-alpha.1) along with Jest. One of my test scripts requires waiting for a specific function to be invoked before proceeding with the remaining test logic, and I'm unsure about the best approach to achieve this. To illustrate this scenario, I prepared a sample application using Sencha Fiddle. The complete code for the app along with its running instance can be accessed here: . Within the app folder in the fiddle, there is a Test component containing a straightforward controller with an onAdd function, which I aim to wait for execution before continuing as other tests rely on its content. By utilizing the following code line in dev tools, the function can be called: Ext.ComponentQuery.query('test')[0].getController().onAdd (it's crucial that the activeElement is set to the preview iFrame document.getElementsByName('fiddle-run-iframe')[0] within the fiddle). This enables me to access the function in driver.executeScript similarly, but I'm uncertain about how to properly wait for its invocation beforehand. My attempt at leveraging the mock/spy functionality in Jest failed because jest was not recognized inside driver.executeScript, preventing calls to jest.fn or jest.spyOn. A sample test script aligned with the sample app demonstrates what I'm trying to achieve, though it currently throws an error due to the absence of jest definition within driver.executeScript.

const {Builder, By, Key, until} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

const driver = global.driver = new Builder()
            .forBrowser('chrome')
            .setChromeOptions(new chrome.Options())
            .build();

jest.setTimeout(10000);

beforeAll(async () => {
    await driver.manage().window().maximize();
    await driver.get('https://fiddle.sencha.com/#view/editor&fiddle/2o6m');
});

afterAll(async () => {
    await driver.quit();
});


describe('check title', () => {
    it('should be SAMPLE STORE LOAD', async () => {
        expect(await driver.wait(until.elementLocated(By.css('.fiddle-title'))).getText()).toBe('SAMPLE STORE LOAD');
    });
});

describe('check store add', () => {
    it('should call add function', async () => {
        let spy;

        await driver.switchTo().frame(await driver.findElement(By.name('fiddle-run-iframe')));
        await driver.wait(until.elementIsNotVisible(await driver.wait(until.elementLocated(By.xpath('//div[starts-with(@id, "loadmask")]')))));
        await driver.executeScript(() => {
            const test = document.getElementsByName('fiddle-run-iframe')[0].contentWindow.Ext.ComponentQuery.query('test')[0];
            spy = jest.spyOn(test.getController(), 'onAdd'); //This throws an error since jest is not defined inside driver.executeScript
        });

        expect(spy).toHaveBeenCalled(); //wait for onAdd function to be called before continuing
    });

    //additional tests occur here after wait...
}); 

The iframe navigation-related logic can be disregarded as it's solely relevant to the fiddle environment where the app runs within an iframe. In actuality, my application is not contained within an iframe. Nevertheless, I believe this script effectively conveys my objective of awaiting the onAdd function call prior to proceeding with the testing processes. Unsure if Selenium, Jest, a blend of both, or an alternative testing tool would be suitable for accomplishing this task. Being relatively new to test writing, this marks my first time seeking guidance on Stack Overflow, so I apologize for any lack of clarity in my explanation. Happy to provide additional information and grateful for any insights or advice!

Answer №1

In my opinion, combining two different testing frameworks in a single test may not always be the most effective approach. Here are some alternative thoughts on how to handle a similar situation with minimal theory:

Selenium is excellent for simulating end-user behavior in a browser. It can perform actions such as clicks and text inputs, as well as retrieve information from a browser window, like element presence, texts, and styles.

Jest, on the other hand, is a unit testing framework specifically for testing JavaScript code.

The method executeScript belongs to Selenium and executes any JavaScript code within a browser. However, the browser itself has no knowledge of jest, so encountering the error you mentioned is expected. Your project, on the other hand, is aware of jest because it is explicitly imported into the project.

Addressing the question of how to verify in Selenium that a JavaScript function has been called:

  1. A common solution is to wait until there is a visible change on the browser screen, such as an element appearing, disappearing, or a style modification.

Here is an example of waiting for a condition in JavaScript.

  1. (a workaround) Another option is to include a flag in the JavaScript code of your application that starts as false before the function is called and then changes to true after the function is executed. You can then access this flag's value using executeScript.

Some possible implementations can be found here.

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

Issue with starts-with() function in Internet Explorer 8

Having trouble identifying a button with the following xpath. It works well in Firefox, but not in IE8. //input[starts-with(@src,'/images/btn_signin.gif')] The full attribute for this element is: /images/btn_signin.gif?osCsid=468e46e5277f56b3e ...

Can ngFor be utilized within select elements in Angular?

I'm facing an interesting challenge where I need to display multiple select tags with multiple options each, resulting in a data structure that consists of an array of arrays of objects. <div class="form-group row" *ngIf="myData"> <selec ...

Is it possible to have animations play in reverse once they have completed running?

Hi there! I'm currently tinkering with the transitioning animations for my navigation button. I've successfully implemented the opening animation where the three bars morph into a single line and the menu slides out. Now, I'm looking to crea ...

Error encountered when running NPM start - file path unable to locate JSON package file

Hello everyone, I'm new here and appreciate any help in advance! I'm currently working on my first project and encountering some challenges. The biggest one is that whenever I try to run npm start, I keep getting an error message: I've att ...

What could be the reason for the text not showing up?

I'm currently working on developing a "MEME Generator" but I've hit a roadblock at this stage. Whenever I: upload > Enter Text > Submit All of the JavaScript changes revert back to the default state. It seems like I might be overlooking s ...

Using ChartsJs to visualize input data formatted in the German data format

I am relatively new to working with Charts.js, but I will need it to generate some visually appealing graphs for my website. In the background, I have a Django project running that calculates a specific set of numbers for me. Due to the language setting in ...

When attempting to retrieve the data from a JSON file using an XMLHttpRequest, the result that is returned is [object object]

I am currently studying JSON and found a helpful guide on w3schools. Here is the code provided in the guide: https://www.w3schools.com/js/tryit.asp?filename=tryjson_ajax The guide also includes a sample JSON file: https://www.w3schools.com/js/json_demo.t ...

Get the application/pdf document that was just sent to you from the software backend

I am facing an issue with downloading a PDF file sent from the backend. Upon receiving a blob response, I notice that when I download and view the file, the sheets are empty, matching the expected number of sheets. Could this be a coding problem? Current ...

What is the best way to conduct synchronous testing of animations in AngularJS version 1.3.15?

Encountering a migration issue with angular-animate.js while transitioning from version 1.2 to 1.3. Here is the animation code snippet: 'use strict'; angular.module('cookbook', ['ngAnimate']) .animation('.slide-down& ...

Discovering the previously dropped value from a droppable div

Currently, I am developing a dynamic formula generator using jQuery's drag and drop functionality. Here is what I have accomplished so far: I have two lists: <ul id="head"> <li class="horizontal">Salary</li> <li class="h ...

Implementing Asynchronous Custom Validators in Angular 4

I've encountered the following code snippet: HTML: <div [class]="new_workflow_row_class" id="new_workflow_row"> <div class="col-sm-6"> <label class="checkmark-container" i18n>New Workflow <input type="che ...

The JavaScript functionality is disrupted by the getCurrentPosition function on the Chrome

I'm having an issue with my webpage that displays Google Maps. I am using getCurrentPosition over http and receiving a warning from the Google API. The problem is that it's also breaking the JavaScript, which then ruins everything. This code was ...

What is the maximum allowable size for scripts with the type text/json?

I have been attempting to load a JSON string within a script tag with the type text/json, which will be extracted in JavaScript using the script tag Id and converted into a JavaScript Object. In certain scenarios, when dealing with very large data sizes, ...

How can we eliminate the modal-open class in Angular when transitioning to a different URL?

Currently, I am facing an issue with a bootstrap modal. There is a button inside the modal which upon clicking should navigate the current component to another component named 'questions'. The problem arises when the new component is loaded, as t ...

Is it possible to utilize getServerSideProps with a functional component in Next.js?

Is it feasible to execute the server side props within a component in NextJS? From my understanding, getServerSideProps fetches the data upon entering the page, but is it achievable for it to run during the rendering of a component? The scenario I have is ...

showcasing pictures at varying time intervals

My challenge is to create a dynamic display of images that transition with a 0.5-second black screen in between. For example, let's say we have an array called array_img = ["im1","im2","im3"]. The goal is to show "im1" for 3 seconds, followed by a bl ...

Implementing a Class on Page Refresh in Next JS

I am fairly new to using react and nextjs. How can I insert a script in a component to add a class when the page reloads? The code below doesn't seem to work because the page is not yet rendered when I try to add the class for the body tag. const Mode ...

How do I navigate to a different page in Vue.js HTML based on user selection?

Here is my first attempt at writing HTML code: <div class="col-md-4" > <div class="form-group label-floating"> <label class="control-label">Select No</label> <select class="form-control" v-model="or" required=""> ...

Retrieve a single document using Angularfire2 without setting up a listener

I'm facing an issue with angularfire2 v6 and angular 11. Specifically, I am attempting to retrieve a single document from the users collection based on their email without utilizing valueChanges() or snapshotChanges(). Realtime updates are not necessa ...

The jQuery framework is causing AJAX/API data to be duplicated in the

I've been encountering a common issue for which I can't seem to find a straightforward solution. My current challenge involves using an API to fetch JSON data through an AJAX call. Upon receiving the data, it appears twice in both the console an ...