"Disabling the promise manager in selenium-webdriver: A step-by-step guide

According to the information provided on https://code.google.com/p/selenium/wiki/WebDriverJs#Promises, the selenium-webdriver library utilizes an automatic promise manager to streamline promise chaining and avoid repetitive tasks.

However, there are situations where the assumption made by the promise manager about chaining successive calls may be inaccurate and need to be turned off.

Consider the following scenario:

var isLoaded = function (browser) {
    var waitForJS = waitForElement(browser, By.css('body.js'));
    var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));

    return Promise.any([waitForJS, waitForMobile]);
};

In this case, I aim to develop a universal function that will wait for either of the two conditions to be met, regardless of whether it's a mobile landing page or desktop site.

Unfortunately, the promise manager interprets it differently

var isLoaded = function (browser) {
    var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
    var waitForJS = waitForElement(browser, By.css('body.js')).then(function () {
        return waitForMobile;
    });

    return Promise.any([waitForJS, waitForMobile]);
};

This implementation can never resolve for the non-mobile situation, as only one of the conditions can be true at any given time.

Is there a way to disable the promise manager entirely and manually schedule all calls?

Below is the definition of waitForElement

var waitForElement = function (browser, element, timeout) {
    return browser.wait(until.elementLocated(element), timeout);
};

Answer №1

If you want to achieve your desired outcome easily, consider using a CSS selector that searches for either one id or the other. For instance, in this demonstration of delayed loading, we are seeking an element with either #foo or #bar. Therefore, we utilize the selector #foo, #bar. In your situation, it could be body.js, #mobile_landing_page. This approach is efficient as it minimizes the back-and-forth communication between your Selenium script and the browser.

var webdriver = require('selenium-webdriver');
var By = webdriver.By;
var until = webdriver.until;
var firefox = require('selenium-webdriver/firefox');
var Promise = require('bluebird').Promise;

var browser = new firefox.Driver();

browser.get("http://www.example.com");

// Randomly determine the element we will search for
var flip = Math.round(Math.random(0, 1));
var id = flip ? "foo": "bar";
console.log("We'll simulate the delayed loading of an element with id", id);

var waitForElement = function (browser, element, timeout) {
    return browser.wait(until.elementLocated(element), timeout);
};

var isLoaded = function (browser) {
    return waitForElement(browser, By.css("#foo, #bar"));
};

// Simulate the delayed loading of the element we are searching for
browser.executeScript('\
var id = arguments[0];\
setTimeout(function () {\
  var el = document.createElement("div");\
  el.id = id;\
  document.body.appendChild(el);\
}, 1000);\
', id);

isLoaded(browser);
browser.quit();

Answer №2

While this information may be considered outdated, for those who stumble upon this post during or after 2017, here's a helpful suggestion:

Promise.any is actually a bluebird feature that returns the first resolved item.

If you're looking to wait for both items to resolve, the appropriate approach is to use Promise.all.

You can implement it like so:

var checkLoadingStatus = function (browser) {
    var waitForJS = waitForElement(browser, By.css('body.js'));
    var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));

    return Promise.all([waitForJS, waitForMobile]);
};

// Utilize it in this manner:
checkLoadingStatus(browser)
.then((elementCheck) => {
  const hasBodyJsTag = elementCheck[0]
  const hasMobileTag = elementCheck[1]
  console.log('Element Status:', elementCheck)
})

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

Automated web scraping using the power of Selenium

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC OUTPUT_FILE_NAME = 'output0.txt' driver = webdriv ...

Toggle the menu using jQuery on unordered list items

Below is the HTML code I am using : <ul class="main-block"> <li class="firstLevel"> <a href="#category">EXAMPLE CATEGORY 1</a> <ul class="dijete"> <li class="child"> <a href="some-sub-categ ...

Tips for creating a proper XPath expression with the AND operator

When testing our app on various environments, the ID of a particular element differs. The div ID in question is: CoredataForm:sec2_natural:grid1:left_section_natural:profession:selectProfession_auto_complete_force:ajax The parts marked in bold are consis ...

Select a specific item from an array and reveal the corresponding item at the matching index in a separate array

I'm working on a project where I have a list of elements that are displayed using a ng-repeat and I am using ng-click to retrieve the index of the element in the array that I clicked on. Here is the HTML code snippet: <ul> <li ng-repeat=" ...

Encountering an issue when verifying internal links using BeautifulSoup and Selenium

Want to know how to combine absolute and relative urls? Check out this link. Currently, I am trying to validate internal links using BeautifulSoup and Selenium. The script functions properly for full url paths like: <a href="http...."/> ...

Troubleshooting: Why Isn't Calling a PHP Function from AJAX Working

I'm attempting to utilize AJAX to call a PHP function. Here's the script I've implemented. <script type="text/javascript" src="jquery.1.4.2.js"> $(document).ready(function () { // after EDIT according to ...

Issue with making a call to retrieve an image from a different directory in ReactJS

This is how it appears <img className='imgclass' src={"../" + require(aLc.value)} alt='' key={aLc.value} /> I am trying to create a path like ../m/b/image.jpg, where aLc.value contains the path /m/b/image.jpg. I need to add only ...

What is the best way to retrieve all string constants from HTML or JSX code?

UPDATE: I recently developed my own babel plugin CLI tool named i18nize-react :D I am currently in the process of translating an existing react application from English to another language. The string constants in the JSX are all hardcoded. Is there a sim ...

Custom providers do not override Angular UrlResolver

In my Angular application, I am trying to implement a custom UrlResolver provider to incorporate cache breaking logic. I came across this question on Stack Overflow: . Unfortunately, it seems that overriding the default compiler UrlResolver using a provid ...

What's the best way to detect and handle incorrect input from faker to ensure my automation runs smoothly without crashing?

Scenario A primary webpage displays a table of individuals along with an "add new person" button. Upon clicking the button, a modal window appears containing various input fields and selection options for adding a new individual. The "name" field has vali ...

When the checkbox is ticked, icheck will make a POST request, but it won't

I am currently experimenting with using icheck to handle POST requests for a temporary table. My goal is to add an entry when a box is checked and remove it when unchecked. Currently, when I check the box, it alerts me and successfully stores the informati ...

Executing a conditional onClick function when the page loads

I have implemented a php-based authorization system that loads different authorization levels into a JavaScript variable. My goal is to disable certain onclick events based on the user's authorization level. I've come up with the following code ...

Include a serial number column when exporting a datatable to a PDF file

Currently, I am in the process of developing an e-commerce project using HTML and Javascript. One important aspect of my project involves displaying the details of ordered products. To achieve this, I have implemented Jquery Datatable to showcase the neces ...

Ways to display the values of angular variables within ng-bind-html

Converting HTML content from a database saved as varchar to front end JavaScript code can be tricky. The content is stored in a variable called vm.htmlContent and must be displayed as HTML on a web page. To achieve this, the ng-bind-html angular directive ...

SimulatedGreg encountered an error message with Electron-Vue-Vuetify: [Vue warn]: The custom element <v-app> is not recognized - have you properly registered the component?

Greetings, I extend my gratitude for extending your assistance towards resolving my current predicament. The issue at hand arose early this morning around 9 am and despite hours of troubleshooting up to 3 pm, the solution continues to evade me. Countless Y ...

Manipulate the visibility of a child element's dom-if based on a property retrieved from the parent element

Exploring the world of Polymer, I am eager to tackle the following scenario... I have a binding variable called {{readonly}} that sends data from a parent Dom-HTML to a child Dom-HTML in my Polymer project. The code excerpt looks something like this... C ...

Import the .obj file along with its original color information, without the need for the accompanying

I am facing a challenge with a .obj file that appears colored in software like MeshLab or Microsoft's 3D builder. However, there is no .mtl file linked to it. When I try to open it in ThreeJs using the most basic method, it shows up as grey. var load ...

How can I align Javascript output vertically in the middle?

I am currently facing an issue with a JavaScript clock displaying in a narrow frame: <!DOCTYPE html> <HTML> <HEAD> <TITLE>Untitled</TITLE> <SCRIPT> function checkTime(i) { if (i < 10) { ...

The issue with jquery slideToggle is that it mistakenly opens all divs instead of just the specific div that should

My website has a dynamic page with a variable number of <div> elements. The concept is that users can click on the + symbol, which is represented by an <img> tag, to display the corresponding div. Currently, my code includes: PHP/HTML $plus ...

error occurred while looping through json array

i am encountering an issue with a code that keeps returning an "undefined" message instead of the expected HTML output. Purpose of function: the aim of the following function is to display notifications in a manner similar to those on Facebook. The code se ...