Protractor: Analyzing all hyperlinks and conducting tests on a webpage

My goal is to count the number of hyperlinks on a page and check if they are functioning properly. While I can successfully count all the links and display the tally in JavaScript, I am facing difficulties returning that value in protractor via Command Line.

Update Code based on Answers:

browser.waitForAngularEnabled(false);
describe('Clicks on the correct Drupal hyperlink', function() {

  it('should find all links', function () {
    browser.get('file:///C:/Users/Dasman/Documents/PROTRACTOR_E2E_TESTING/TestSite.html');
    let allLinks = element.all(by.tagName('a'));
    allLinks.count().then(function(link_tally){
      console.log('There are a total of ' + link_tally + " links on this page with proper tags.")
    })
  browser.sleep(2000);

  // A Protracterized httpGet() promise
function httpGet(siteUrl) {
  var http = require('http');
  var defer = protractor.promise.defer();

  http.get(siteUrl, function(response) {

      var bodyString = '';

      response.setEncoding('utf8');

      response.on("data", function(chunk) {
          bodyString += chunk;
      });

      response.on('end', function() {
          defer.fulfill({
              statusCode: response.statusCode,
              bodyString: bodyString
          });
      });

  }).on('error', function(e) {
      defer.reject("Got http.get error: " + e.message);
  });

  return defer.promise;
}

it('should return 200 and contain proper body', function() {
  httpGet(allLinks).then(function(result) {
    allLinks.count().then(function(statusCode){
      console.log('Status code is: ' + statusCode)
    })
      expect(result.statusCode).toBe(200);
      expect(result.bodyString).toContain('Apache');
  });
});
    });
});

Moreover, I aim to "check" the links to verify their functionality. Is there a method to visit a URL and click on each link to open them in separate windows? Or retrieve an attribute indicating whether the link works or has a valid URL?

Initially, I used xpath to locate the id and manually clicked on the link while visually verifying as the test progressed. However, given the average page contains 15-20 links, I require a more automated approach.

Ernst's answer guided me towards the solution, although it required some restructuring and encapsulation of code: https://github.com/SDasman/Angular_Protractor_End2End_Tests/tree/master/LinkCheck

Answer №1

If you want to display the count in the console, you can achieve it by following this code snippet:

//find all links
let linkCount = element.all(by.css('a'));

// count links, resolve promise with then() and log the result
linkCount.count().then(function(cnt){
    console.log('Total links = '+cnt);
});

//click each of the links:
linkCount.click()

You can learn more about count(), then(), and element.all() at:

To verify the response code of your links, it's a bit tricky as Protractor doesn't natively support such requests (see here).

Nevertheless, two Stack Overflow posts here and here offer solutions.

To test one by one, you could use getAttribute('href'). Here's a basic example (Note: not tested, adapted from the mentioned SO answers):

linkCount.each(function(elem){
    elem.getAttribute('href').then(function(link){
        this.httpGet("http://localhost:80").then(function(result) {
            expect(result.statusCode).toBe(200);
        });
    });
});

// A customized httpGet() function using promises
this.httpGet = function(siteUrl) {
    var http = require('http');
    var defer = protractor.promise.defer();

    http.get(siteUrl, function(response) {

        var bodyString = '';

        response.setEncoding('utf8');

        response.on("data", function(chunk) {
            bodyString += chunk;
        });

        response.on('end', function() {
            defer.fulfill({
                statusCode: response.statusCode,
                bodyString: bodyString
            });
        });

    }).on('error', function(e) {
        defer.reject("Got http.get error: " + e.message);
    });

    return defer.promise;
}

Answer №2

If you want to extract text from every link and calculate the total number of array elements, you can achieve it using the following code snippet:

let allLinks = element.all(By.tagName('a'));
allLinks.getText().then(function(linkText) {
let numberOfLinks = linkText.length;
console.log(numberOfLinks);
})

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

Using the Array.prototype.map() method in Apollo client with Reactjs requires an arrow function to return a value

I am currently developing a project management tool using reactjs and graphql. Upon sending a query from reactjs, I receive the following data as a response: { "data":{ "clients":[ { "name":"Okoye ...

Is there a way to pass information from Express.js to React without using an API?

My goal is to build a Multi Page APP using both react and express. I find myself uncertain about how to access data sent by express in react without utilizing an API. I am curious if react has the capability to retrieve information stored in HTML props t ...

What is the best way to utilize JQuery AJAX to send XML data for a delete request?

I am having trouble sending XML type data to the backend using jQuery and AJAX as a DELETE request. When I do this, I receive an empty array from the backend's request body. How can I properly send the ID? Below is the code I am using: function delet ...

4 HTTP requests were made with the user._id being undefined

I'm currently developing a basic Express application for managing image uploads and searches. While the upload functionality is working smoothly, I'm encountering issues with req.user._id being invalid in the get request. Any possible reasons for ...

``There seems to be an issue with the visibility of Three.js OBJ MTL Loader

Utilizing the obj+mtl loader to import my OBJ files into the scene and loading textures from the mtl file. For example: newmtl initialShadingGroup illum 4 Kd 1.00 1.00 1.00 Ka 0.00 0.00 0.00 Tf 1.00 1.00 1.00 map_Kd 6922529901031.jpg map_Bump 69225299010 ...

The result of calling Object.keys(obj) is not being shown on the screen

I have come across a code snippet that functions perfectly fine in the console, however, it is not being displayed on the screen. Any assistance in resolving this issue would be greatly appreciated. {Object.keys(flags).forEach(product => { return ( ...

transferring information to a PHP page using JavaScript without using AJAX requests or form submissions

I am currently working on a PHP page where I receive POST data using some functions, without relying on AJAX for page refresh. At the moment, I have a form that includes hidden fields holding dynamic data, which is then sent using JS like this: document.m ...

Modifying the status of a link using jQuery

My ajax function handles two different outcomes based on the class of the link that is clicked. To avoid reloading the entire page when the link is clicked, I have utilized the following code: Everything seems to be working fine, however jQuery still rec ...

The JQqplot graph is failing to display correctly following an ajaxpost operation

When drawing a chart in two different scenarios, the first scenario is during the onload event and the second one is after the successful completion of an ajax post. The same code is being called in both scenarios. During the onload function, the chart l ...

The Google Picker API encounters a server error when attempting to retrieve the OAuth token after being released as a private add-on

Recently, I encountered a puzzling issue with my script that utilizes the Google Picker API. During testing, everything worked flawlessly until I decided to publish it as a private add-on. From that point on, the script's getOAuthToken function starte ...

Unraveling the JSON section within a intricate text document

Embarking on the development of a desktop application using Electron, I aim to parse files and present data extracted from these complex files. These files contain intricate information. My current challenge involves extracting JSON data from a convoluted ...

Adjust Node visibility as User scrolls to it using CSS

Suppose I have a structure like this: <br><br><br>...Numerous BRs...<br><br><br> <div id="thetarget"></div><div id="show"></div> <br><br><br>...Numerous BRs...<br><br&g ...

Looking for Sha1 encryption functionality in jQuery or JavaScript?

I am currently using sha1 encryption coding in PHP <?php echo hash('sha1', 'testing'.'abcdb'); ?> However, I need this encryption to work on a page named xyz.html, causing the current block of code to not function prop ...

Enhance your Ant Design Area chart by eliminating unnecessary canvas margins

I am trying to customize the Ant Design Area chart so that it fits perfectly inside its container without any margins or padding on the sides. However, I have been unable to find the specific attribute in Ant's documentation for this adjustment. Addit ...

Encountering an Issue while Deploying a create-react-app to Heroku

Despite trying various online remedies, I am still encountering an error while attempting to deploy a simple React.js app on Heroku. The app successfully builds when I execute git push heroku master, but upon opening it, I consistently receive an applicati ...

I encountered an issue where I was unable to execute an Ajax call on the Chrome browser while working with

My files are located in the C:/xampp/htdocs directory. I am trying to call: {"name":"john", "age":19.4} file from: <!DOCTYPE html> <html> <head> <script type="text/javascript"> function ajax_json() { var hr = new XMLHttpRequ ...

What could be the reason for my failing express test?

I'm in the process of configuring a server using Node/Express and I want to write ES6 code, so I've incorporated babel into my setup. Currently, the server is operational, and I can successfully make the necessary requests. However, I am facing ...

Error in HTML5 video: Unable to access property '0' as it is undefined

I am trying to create a simple block displaying an HTML5 video tag. I want the ability to play different videos along with their titles from a JSON file by using previous and next buttons. Clicking the next button should play the next video, and the same g ...

What steps should I take to create a plugin for a library if defining it as a peerDependency does not provide a specific implementation for me to work with?

Requirements for My Plugin: I'm currently in the process of developing a new plugin that is dependent on popularLibrary.js. Here are the key points about my plugin: It will not function properly if popularLibrary.js is missing. It is designed to wo ...

When the value equals 25

I am seeking to implement a text field where users can input a number, and based on whether it's correct or not, display "image a" for the correct answer and "image b" for an incorrect one below the text field. I want users to have multiple attempts u ...