Setting up various functionalities using guarantees

Building on the topic of setting a Firefox profile with Protractor from this discussion.

Referencing the setFirefoxProfile guide, it's noted that a customized Firefox profile can be established using specialized JavaScript code found in this "helper" script, leveraging libraries like firefox-profile and q for dynamic profile creation.

This method was effective until attempting to implement multiple browsers while configuring multiCapabilities:

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',

    multiCapabilities: [
        {
            browserName: 'chrome',
            specs: [
                'footer.disabledCookies.spec.js'
            ],
            chromeOptions: {
                prefs: {
                    'profile.default_content_settings.cookies': 2
                }
            }
        },

        ...
        // other capabilities here
        ...

        helper.getFirefoxProfile()    
     },

     ...
}

However, an error is encountered in this setup (full details available here):

Spec patterns did not match any files.

The issue seems to stem from the absence of a specs key within the Firefox profiles, resulting in no tests being identified for execution.

Attempts were made to include specs directly into the capabilities object inside the helper script, yet the error persists.

How can this error be resolved when configuring Firefox profiles alongside multiCapabilities?


To navigate around this issue, a separate Protractor configuration file was created specifically for Firefox configurations (using capabilities), with a setup involving running Protractor twice - once for the "Firefox with profile" config and another for all other browsers.

Answer №1

Currently, when using protractor without multicapabilities, only promises can be accepted as capabilities. This limitation arises because multiCapabilities executes each task in a separate process, making it impossible to pass a promise (function) (single capabilities work since there is no forking involved).

An alternative approach would involve resolving capabilities in the launcher before passing them into the new processes; however, this would disrupt the ability to configure proxies (https://github.com/angular/protractor/pull/1040), which relies on capability promises being resolved after driverProvider setup.

While I cannot think of a straightforward solution without significant restructuring, it is certainly feasible. I have raised an issue with Protractor (https://github.com/angular/protractor/issues/1594). Please monitor that and provide your input if this is a feature you require or if you have alternative implementation ideas.

For the time being, you will need to resort to the workaround mentioned in your original inquiry.

UPDATE

https://github.com/angular/protractor/pull/1629 now supports this functionality. With protractor 1.6 onwards (or by syncing to master), you can supply a function to config.getMultiCapabilities similar to onPrepare and onCleanup. This function can return a promise for multiCapabilities (i.e., an array of capabilities).

Refer to https://github.com/angular/protractor/blob/master/spec/getCapabilitiesConf.js for an illustrative example.

Answer №2

After reviewing the pull request from @hankduan, I have successfully utilized getMultiCapabilities() to merge different capabilities, including one that is a promise (necessary for setting the firefox-profile):

"use strict";

var FirefoxProfile = require("firefox-profile");
var q = require("q");

exports.config = {
    seleniumAddress: "http://127.0.0.1:4444/wd/hub",

    getMultiCapabilities: function() {
        var deferred = q.defer();

        var multiCapabilities = [
            {
                browserName: "chrome",
                specs: [
                    "footer.disabledCookies.spec.js"
                ],
                chromeOptions: {
                    prefs: {
                        "profile.default_content_settings.cookies": 2
                    }
                }
            },
            {
                browserName: "chrome",
                specs: [
                    "*.spec.js"
                ],
                exclude: [
                    "footer.disabledCookies.spec.js",
                    "footer.disabledJavascript.spec.js",
                    "footer.disabledFlash.spec.js"
                ]
            },
            {
                browserName: "chrome",
                specs: [
                    "footer.disabledFlash.spec.js"
                ],
                chromeOptions: {
                    args: [
                        "--disable-internal-flash",
                        "--disable-bundled-ppapi-flash",
                        "--disable-plugins-discovery"
                    ]
                }
            }
        ];

        // Wait for server readiness or asynchronously retrieve capabilities.
        setTimeout(function() {
            var firefoxProfile = new FirefoxProfile();
            firefoxProfile.setPreference("javascript.enabled", false);
            firefoxProfile.encoded(function (encodedProfile) {
                var capabilities = {
                    "browserName": "firefox",
                    "firefox_profile": encodedProfile,
                    "specs": [
                        "footer.disabledJavascript.spec.js"
                    ]
                };
                multiCapabilities.push(capabilities);
                deferred.resolve(multiCapabilities);
            });
        }, 1000);

        return deferred.promise;
    },

    ...

};

I hope this example serves as a helpful reference for others in the future.

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

Encountering Errors with Multiple Controllers in my Angular JS App

As a beginner in Angular JS, I understand that the declaration below is necessary in the js file to make angular JS Controller work: var app = angular.module('myApp', []); app.controller('ctrlOne', function(){ }); However, I recently ...

Issue with form validation, code malfunctioning

I am struggling to figure out why this validation isn't working. Here is the HTML code I'm using: <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type='text/javascript' src="scripts. ...

Send input values to a JavaScript function from an onchange event

I'm facing an issue with using AJAX to update a section of my website when the drop-down box is changed. The problem I am encountering is passing the parameters correctly to the function. Below is the HTML code: <script type='text/javascript ...

Express throwing module errors

I encountered an issue while attempting to expose a REST service in an electron app using expressJS. Following a tutorial, I added express and @types/express to the project. However, when trying to implement a "get" method and running the build with ng bui ...

Ways to prevent the remaining time from indicating the duration

Welcome to my website. If you have any tips on creating dropdowns in markdown, please share! Here is the code snippet: // Add your JavaScript code here This script is designed to play music from a file. To use it, simply click the play button and upload a ...

The issue arises when React child props fail to update after a change in the parent state

Here's the main issue I'm encountering: I am opening a websocket and need to read a sessionId from the first incoming message in order to use it for subsequent messages. This should only happen once. I have a child component called "processMess ...

Utilizing Node Mailer and Sendgrid to send emails in an Angular MEAN stack project with the angular-fullstack framework generated by Yeoman

Trying to figure out the best location for the code responsible for sending an email through a contact form in my Angular App using angular-fullstack MEAN stack from Yeoman. I managed to implement the email sending logic in the app.js file on the server s ...

How to send the file path to an API in JavaScript to convert it

I am currently working on a web application that allows users to upload a wav file and convert it to mp3 format. I have successfully implemented the wav to mp3 conversion and saving it to the project folder. However, I am facing an issue with dynamically p ...

Is there a way to retrieve a label's text using their class name within a loop?

I have multiple labels sharing the same classname, each with different text. My goal is to iterate through them and extract the text they contain. Here is the example markup: <label class="mylabel pull-left"> Hello </label> <label class="m ...

I wonder what the outcome would be if I used res.send to send a JSON file instead of res.json

Is it possible to send a JSON file using res.send in NodeJs instead of res.json? What are the potential consequences of doing this and why is it recommended to avoid this practice? ...

Parameterized function call on click event

There is a function defined as follows: menu[0].onclick = function() { filters.reset_all(); clients.get(); } This function gets called when the user clicks on the first menu element. Now, I need to invoke this function from another place and here ...

Retrieve an array from a JavaScript file, transfer it to PHP, and then convert it into JSON format

I have a JavaScript file that contains data in the form of an array. http://localhost/js/data.js The information looks something like this: var subjectCodeArray=["CS/ Computer Science","AF/ Art Faculty",...]; Now, I need to access the data from the "sub ...

Explore JSTree by navigating and modifying individual nodes

Looking for some guidance with JSTree. I am new to it and really interested in learning how to traverse JSTree to edit each node. I attempted to write a recursive function to go through each node, but what puzzles me is, I extracted the data by using var ...

Order sorting of comments in bootstrap-angular.js

I'm struggling to figure out how to display comments in a specific order by date, author, and rating in the input section. I also want them to be sortable in descending order if -date is typed. Check out this link for more information on comments sor ...

What steps can be taken to resolve an ESLing error in this situation?

Check out this code snippet: <template v-if="isTag(field, '')"> {{ getItemValue(item, field) ? getItemValue(item, field) : '&#8211'; }} </template> An issue has been identified with the above code: Er ...

The function was not invoked as expected and instead returned an error stating "this.method is not

I need help with an issue in my index.vue file. The problem lies in the fancy box under the after close where I am trying to call the messageAlert method, but it keeps returning this.messageAlert is not a function Can someone please assist me in resolving ...

Why is the code to check if the user has scrolled to the bottom not working in Chrome but working in Microsoft Edge?

I have been using this code to determine if a user has scrolled to the bottom of a page, but I've run into some issues specifically with Google Chrome. Surprisingly, the code works flawlessly on Microsoft Edge. On Google Chrome, when I scroll to the ...

Automatically identify the appropriate data type using a type hint mechanism

Can data be interpreted differently based on a 'type-field'? I am currently loading data from the same file with known type definitions. The current approach displays all fields, but I would like to automatically determine which type is applicab ...

Issue with generating PDF in AngularJS: pdfMakeTypeError occurs due to inability to read 'ownerDocument' property within html2canvas

Whenever I try to export by clicking the export button, this code is triggered: $scope.export = function() { html2canvas(document.getElementById('balanceSheet')).then(function(canvas) { document.body.appendChild(canvas); ...

What is the best approach for triggering an action upon both keyup events and item selection in a text input field with a datalist

I am looking for a simple solution to my issue. I have a text input box that is connected to a datalist. I am able to use jQuery to trigger an event for every key typed ("change keyup"), but I also need to trigger an event when an item is selected from the ...