Issue arises as Protractor's custom locator is unable to find the desired element

I decided to enhance the identification and interaction process in Protractor by adding a custom data attribute called data-test-id to specific elements. To achieve this, I created a custom locator within the onPrepare callback function in my conf.js file. Here's the custom locator implementation:

onPrepare: function () {
    by.addLocator('testId', function(value, parentElement) {
      parentElement = parentElement || document;
      var nodes = parentElement.querySelectorAll('[data-test-id]');
      return Array.prototype.filter.call(nodes, function(node) {
        return (node.getAttribute('[data-test-id]') === value);
      });
    });
  }

One of the elements in my Angular app is an h1 tag containing the text 'Home'. I assigned the data-test-id attribute to it as shown below:

<h1 data-test-id="test-element">Home</h1>

Furthermore, here is the test script written in Protractor:

test.js:

describe('Navigate to the website.', function() {
    it('Should have the Heading as Home', function() {
        browser.get('http://localhost:8888/#/');
        browser.waitForAngular();

        var textValue = 'Home';
        var heading = element(by.testId('test-element'));

        expect(heading.getText()).toEqual(textValue);
    });
});

conf.js:

exports.config = {
  //directConnect: true,
  seleniumAddress: 'http://localhost:4444/wd/hub',
  // Capabilities to be passed to the webdriver instance.
  capabilities: {
    'browserName': 'chrome'
  },

  // Spec patterns are relative to the current working directly when
  // protractor is called.
  specs: ['test.js'],

  // Options to be passed to Jasmine-node.
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000
  },

  onPrepare: function () {
    by.addLocator('testId', function(value, parentElement) {
      parentElement = parentElement || document;
      var nodes = parentElement.querySelectorAll('[data-test-id]');
      return Array.prototype.filter.call(nodes, function(node) {
        return (node.getAttribute('[data-test-id]') === value);
      });
    });
  }
};

However, upon running the test, I encountered the following error message:

1) Navigate to the website. Should have the Heading as Home
Message: NoSuchElementError: No element found using locator: by.testId("test-element")

I need assistance in resolving this issue and making the test function correctly. Any insights would be greatly appreciated.

Answer №1

When fetching the attribute, make sure to request data-test-id instead of [data-test-id]. It seems like a simple mistake from copying and pasting.

Change this:

return (node.getAttribute('[data-test-id]') === value);

to this:

return (node.getAttribute('data-test-id') === value);

Answer №2

I encountered a similar issue and found the following solution to be effective:

by.addLocator('lid', function(value, parentElement) {
        var nodes;

        if(parentElement)
            nodes =  parentElement.querySelectorAll();
        else
            nodes = document.querySelectorAll('body *');


        return Array.prototype.filter.call(nodes, function(node) {
            if( node.hasAttribute("lid") && node.getAttribute('lid') === value)
                return node;
        });
    });

The key point is that querySelectorAll() requires the input in the form of 'tag'. If no parentElement is specified, it will search for all tags under the 'body' tag. Otherwise, it will search for all elements within the parentElement. Then, it loops through each element to check if the 'lid' attribute exists. If it does, it verifies the value, returning the element if it matches the desired value.

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

Exploration of features through leaflet interaction

Attempting to plot bus routes on a map using leaflet with geojson for coordinates. Facing issues with making the bus line bold when clicked, and reverting the style of previously clicked features back to default. Current Progress function $onEachFeature( ...

Chrome crashes randomly due to WebDriver issues

While executing my test suite in Google Chrome using Selenium's ChromeDriver, the browser frequently crashes with a message saying "Whoa! Chrome has crashed. Relaunch now?". This unexpected behavior leads to non-deterministic outcomes in the code. im ...

Discovering the locator of an element that behaves like getText() in automation

Looking for a way to locate an element similar to getText() in automation testing? I am currently testing an app module with a day ruler ranging from 1 to 50. Each time I access the module, the day value changes within this range. How can I dynamically re ...

Use the `string.replace()` method to swap out strings in a nested object with values from a separate file

Is there a way to swap out the placeholders __fruit_type__, __clothing_type__, __fitness_equipment__, __meditation_app__ in collection.js with the corresponding values from values.js? I'm attempting to do this using the string.replace() Method co ...

What are the steps to retrieve information from a REST API with basic authentication?

I am attempting to retrieve data from a website using the HTTP GET method. This particular website requires basic authentication and the data is in JSON format. You can find the REST API website here: () // Insert your code here angular.module(&apos ...

Using Passportjs for user authentication with Angularjs (resource/http get)

I am currently experimenting with integrating Passportjs into an Angular and Express project. My current focus is on testing the Facebook strategy in passportjs. While authentication appears to be successful, I am encountering an issue where it does not n ...

Encountering ERR_EMPTY_RESPONSE in Google Chrome while utilizing BrowserMobProxy for conducting Selenium tests

I have developed a simple method for extracting network traffic data from Chrome: public void saveNetworkTraffic() { System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/bin/chromedriver"); String sFileName = "networkl ...

Finding a way to extract a singular text node after the Span element but before the br tag using Selenium WebDriver

I am trying to retrieve the text between span and br tags. In the HTML snippet below, I am aiming to extract the Orange text: <td role="grid cell"> <span class="ui-column-title">Fruits</span> <span id="all fruits"> "Orange" < ...

Looking to display a gif when a user clicks a button

I need help with making a spinner gif hidden in Unbounce and then show when the user clicks a button. The button is labeled #lp-pom-button-279 and the image is labeled #lp-pom-image-288 My attempts to use JS and CSS have resulted in the gif being either a ...

Modifying an element within a nested array

I am struggling to create a JavaScript function that can update the "checked" value within an object in an array structured as follows: array:[ { id:1, name:"foo", options: [ {id:"one", checked: false}, {id:"two", checked: true} ] ...

Disable the display of meridian in the UI Bootstrap datetime picker

Currently, I am utilizing the ui-bootstrap-datetime-picker with angularJS. I am wondering if it is feasible to directly set the show-meridian options of the time-picker inside the timepickerOptions. ... <input type="text" class="form-control" ...

Is it possible to determine whether a path leads to a directory or a file?

Is it possible to distinguish between a file and a directory in a given path? I need to log the directory and file separately, and then convert them into a JSON object. const testFolder = './data/'; fs.readdir(testFolder, (err, files) => { ...

What is the best method for incorporating the electron binary when using Python along with Selenium for testing purposes?

Currently, I am utilizing Python and Selenium to conduct testing on an electron application. However, upon opening the app through Selenium, it appears that something is amiss with electron as none of the i18n replacements seem to be taking place. Strang ...

AngularJS Upgrading the Scope with $q

Lately, I've been working on updating code that resembles the following: $scope.arrayOfThings = []; function setArrayOfThings() { thingsService.get().then(function (things) { $scope.arrayOfThings = things; }); } $scope.$on(' ...

Optimizing with react and mobX: What You Need to Know

I am new to React and MobX and have been studying various tutorials on using both together. Currently, I am working on creating a form where users can select a product through autocomplete functionality using react-select. Once a product is selected, the i ...

Retrieving the input[text] value in TypeScript before trimming any special characters

One of the tasks I am working on involves a form where users can input text that may contain special characters such as \n, \t, and so on. My objective is to replace these special characters and then update the value of the input field accordingl ...

IE8 - "object does not exist or is undefined" error

Below is the HTML code snippet: <td style="vertical-align: bottom;"><div id="resultCount">n.v.</div></td> Accompanied by this JavaScript code: function processResultCount(data) { $("#resultCount").html(formatNumber(data.res ...

Challenges with compiling Next.js with Tailwindcss and Sass

I recently created a simple template using Tailwind for my Next.js project. Normally, I rely on Tailwind's @layer components to incorporate custom CSS styles. However, this time I wanted to experiment with Sass, so I converted my globals.css file to ...

The gridview fails to update when I attempt to click on the update button

Here is my updated code snippet for the GridView After clicking on the update button, the gridview is not being updated and instead reverting back to its previous value. However, the delete option is working correctly. Id = ( ...

Plupload is not compatible with ng-dialog

I'm currently attempting to integrate plupload into a modal window that is generated by ng-dialog. Here is the code I am using: $scope.showManager = function(){ ngDialog.open({ template: '/template/fmanager.html', controller: &apo ...