Why does WebdriverIO send a POST request for an unused webelement?

Exploring the capabilities of webdriverIO has been quite enjoyable! There are many features of this framework that I already appreciate.

In my investigation, I wanted to see how WebdriverIO handles non-existing elements and lazy element loading in this test:

it('no element, and not used', () => {
    browser.pause(5000)
    let non_exist = browser.$('.nonexist')
});

The output from the test runner is as follows:


[17:23:25]  COMMAND    POST     "/wd/hub/session/6b79fd07-5f5d-42ce-b1e5-f99734aae128/element"
[17:23:25]  DATA                {"using":"css selector","value":".nonexist"}

Reviewing the webdriver server log:


*** Element info: {Using=css selector, value=.nonexist}
17:23:25.840 INFO - Executing: [delete session: 6b79fd07-5f5d-42ce-b1e5-f99734aae128])

It appears that WebdriverIO still sends a POST request to the selenium server, attempting to locate the element upon declaration.

Let's now look at the second test. Here, I declare an element that does not exist on the page but try to use it later:

it('no element, used later in the code', () => {
    browser.pause(5000)
    let myElem = browser.$('.nonexist')
    console.log('AND NOW FAIL!')
    console.log(myElem.getText())
});

The output from the test runner for this scenario is:


[17:30:35]  COMMAND     POST     "/wd/hub/session/05e4115c-ed66-4e47-8a01-c37208d379ab/element"
[17:30:35]  DATA                {"using":"css selector","value":".nonexist"}
AND NOW FAIL!
[17:30:36]  COMMAND     POST     "/wd/hub/session/05e4115c-ed66-4e47-8a01-c37208d379ab/elements"
[17:30:36]  DATA                {"using":"css selector","value":".nonexist"}
[17:30:36]  RESULT              []

Looking at the Selenium Server logs:


*** Element info: {Using=css selector, value=.nonexist}
17:30:36.133 INFO - Executing: [find elements: By.cssSelector: .nonexist])
17:30:36.155 INFO - Done: [find elements: By.cssSelector: .nonexist]

Webdriver IO makes two requests - first during declaration, and then an 'elements' request when attempting to perform an action on the element.

The question arises, why does WebdriverIO attempt to find the element twice in these examples? Although no exceptions are thrown and everything seems to be working fine, I'm curious if this behavior is intentional or possibly a bug?

Answer №1

It is intentional that WebdriverIO does not follow the convention set by the Webdriver Spec where an exception should be thrown if an element is not found. This decision was made to allow for actions to be called on elements that may not yet exist in WebdriverIO. By defining elements in variables and referring to them later, it enhances syntax like so:

var myElem = $('#notExisting')
myElem.waitForExist() // waits for element to exist
console.log(myElem.getText()) // returns text if element shows up

However, attempting to perform actions on a non-existent element will result in failure, as demonstrated here:

var myElem = $('#notExisting')
console.log(myElem.getText()) // THROWS EXCEPTION

While querying non-existing elements may take slightly longer, the benefit of clearer and more readable test code outweighs this minor delay in the long term.

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

Utilizing JQuery Ajax to dynamically replace elements using JQuery functions

My issue is as follows... I am using AJAX and jQuery to populate a form. When the user makes a selection from a dropdown menu, AJAX retrieves data based on the choice and populates the form with this data. Sometimes, new elements are created when the AJA ...

Using webdriver selenium to extract information from various websites

I am attempting to extract data from multiple URLs and save them in a CSV file. However, with the current code that I have, although it successfully opens all three sites, it only saves the data from the final link, including all of its pages. data = {} ...

Guidelines for creating a dynamic filter in Prisma js

I am looking to create a dynamic filter based on user input from the frontend. On mapping the data, I found that the object results appear like this: { id: '2', name: 'yuhu' } The keys 'id' and 'name' need to be dyn ...

Discovering the parameters at your disposal within a callback function can be easily achieved in JavaScript and MongoDB

Being new to JavaScript and web development, I've been self-studying but have encountered many roadblocks. Currently, I'm struggling with understanding functions with callback functions and their parameters. The documentation I've read so f ...

Unable to send an API request from Postman to a database through express and mongoose technology

This is my server.js: const express= require('express'); const app = express(); // const mongoose= require('mongoose'); // load config from env file require("dotenv").config(); const PORT = process.env.PORT || 4000; // middl ...

React does not allow objects as child elements. Instead, render a collection of children by using an array

Encountering an error with this React class Error: Objects are not valid as a React child (found: object with keys {_id, name}). If you meant to render a collection of children, use an array instead. Is there anything amiss here? I am passing the movies ...

Utilize JavaScript to Trigger AJAX HoverMenuExtender in .NET

Within my C# web application, I am attempting to trigger an Ajax HoverMenuExtender using JavaScript, rather than relying on hovering over a designated control. When I set the TargetControlID of the HoverMenuExtender to a control on the page and hover ove ...

Having issues with my code, not sure what's causing the problem (Apache POI)

package apachePOIFrameWork.ObjectRepository; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.Fi ...

Error: An unrecognized symbol '<' was encountered while utilizing $routeparams

In my Angular application with MongoDB, Express, and Node.js, I have a list of flats and I want to add an "Edit" option for each flat. Below is a snippet from my api.js file: api.route('/flats/:id') .get(function(req, res){ Flat.findById(r ...

When using PHP's `json_encode()`, don't forget to append a "1" at the

While utilizing json_encode in my project, I have encountered an issue that is perplexing. On one particular page where I make an ajax call, the resulting json seems to mysteriously add a 1 to the end of the string. The output of my return string appears ...

Launching a headless browser on Ubuntu using either bash or Python with Selenium

I have set up a cron job to run a Python script that utilizes Selenium. Since Selenium requires a display, I have taken the necessary steps of installing Xvfb, initializing the display, and launching Firefox: sudo Xvfb :10 -ac export DISPLAY=:10 firefox ...

Locate elements using Class with Simple Selenium

I'm facing a challenge filling out a phone number on a web portal using Selenium with VBA. Despite the element being loaded, Selenium seems to be unable to locate the text box. This is my code: Dim ch As Selenium.ChromeDriver Sub FillPhoneNumbers() ...

Tips for effectively implementing a curried selector function with the useSelector hook in react-redux

In my project using react-redux with hooks, I encountered a situation where I needed a selector that takes a parameter which is not passed as a prop. Upon checking the documentation, it mentioned: The selector function does not receive an ownProps argum ...

Enable hyperlink to open in a new browser tab after user clicks on button embedded inside an iFrame

<head> </head> <div> <iframe src="https://....."></iframe> </div> https://i.sstatic.net/dk21i.png I'm looking for a way to open the link in a new tab when clicking on this button. Currently, the page loads wi ...

Extracting information from JSON using arrays

I'm facing a bit of a challenge with this one. I've been trying to use jQuery on my website to update an element. It works perfectly fine without using an array of data in JSON, but as soon as I introduce an array of data, it stops functioning. I ...

Looking to alter the CSS of an ID element when hovering over a link on your website?

Irrespective of the positioning of the links in the html, a simple hover effect can trigger changes like switching images or altering backgrounds anywhere on the website. The ideal solution would involve a straightforward method without the need for Javas ...

Data gathered from web sources displayed in a recurring pattern

While writing a python script using selenium, I have encountered an issue with the data being scraped in a strangely repetitive manner. My intention was to extract and parse the first table from a specific webpage as mentioned in my script. Below is the s ...

Detection of collisions using bounding sphere method

In Three.js, each mesh (THREE.Object3D) comes with useful properties like boundingSphere and boundingBox, along with methods such as intersectsSphere and isIntersectionBox. I initially thought I could use these for simple collision detection. However, I n ...

Storing a collection of images simultaneously in Firebase Storage and saving their URLs in a Firestore document using Firebase v9

I am currently working on a form that requires users to input data in order to generate a detailed city document. Additionally, users must upload multiple photos of the city as part of this process. Once the form is submitted, a new city document is create ...

The $route object in vue-router appears to be empty when used with single file components

I am facing an issue while using single file components with vue-router and vue-2.0. The problem I can't seem to resolve is that the this.$route object, when called from a component, always returns empty values. For example: https://i.sstatic.net/ws ...