how to use Protractor on non angularjs website?
Asked Answered
A

13

82

I have found Protractor framework which is made for AngularJS web applications.

How can I use Protractor on a website which is not using AngularJS?

I wrote my first test and Protractor triggers this message:

Error: Angular could not be found on the page https://www.stratexapp.com/ : retries looking for angular exceeded
Adham answered 4/1, 2014 at 22:42 Comment(0)
N
76

If your test needs to interact with a non-angular page, access the webdriver instance directly with browser.driver.

Example from Protractor docs

browser.driver.get('http://localhost:8000/login.html');

browser.driver.findElement(by.id('username')).sendKeys('Jane');
browser.driver.findElement(by.id('password')).sendKeys('1234');
browser.driver.findElement(by.id('clickme')).click();
Necktie answered 7/1, 2014 at 15:42 Comment(4)
just a silly question, has by.id changed to By.id?Percent
@Percent - global.by = global.By = protractor.By; (source - github.com/angular/protractor/commit/…)Necktie
How to find element by class and other means of non angular sites?Tankard
@EaswaramoorthyK by.className . Refer to docsUzzi
R
129

Another approach is to set browser.ignoreSynchronization = true before browser.get(...). Protractor wouldn't wait for Angular loaded and you could use usual element(...) syntax.

browser.ignoreSynchronization = true;
browser.get('http://localhost:8000/login.html');

element(by.id('username')).sendKeys('Jane');
element(by.id('password')).sendKeys('1234');
element(by.id('clickme')).click();
Regenaregency answered 21/4, 2014 at 13:54 Comment(5)
I liked this approach to keep code consistent across the test suit.Vestpocket
This is definetly the best approach when dealing with protractor on non-angular. There's a blog post on this which explains some more stuff. For those searching for E2E, there's also nightwatch.js, intern, casperjs, webdriverSporangium
@Andrei How about pageObjects. when i declare elements out side the functional block and trying to run it is showing me NoSuchElementError code snippet: this.buttonOnLeftSide= browser.driver.findElement(by.className('leftbutton')); this.iframe='emulatorFrame'; this.clickPlusSignOnTemplateEditor= function() { browser.driver.ignoreSynchronization = true; console.log('hey'); browser.driver.switchTo().frame(this.iframe); console.log('inside iframe'); browser.sleep(3000); buttonOnLeftSide.click(); };Anemo
Just put it here in case someone having same issue like mine. Please aware of this approach, it is good but if you want to have fast-fail. You test may run forever in some case/environment although tests are failed.Bicker
im having jasmine.DEFAULT_TIMEOUT_INTERVAL after i click the submit button. any idea?Cataplasia
N
76

If your test needs to interact with a non-angular page, access the webdriver instance directly with browser.driver.

Example from Protractor docs

browser.driver.get('http://localhost:8000/login.html');

browser.driver.findElement(by.id('username')).sendKeys('Jane');
browser.driver.findElement(by.id('password')).sendKeys('1234');
browser.driver.findElement(by.id('clickme')).click();
Necktie answered 7/1, 2014 at 15:42 Comment(4)
just a silly question, has by.id changed to By.id?Percent
@Percent - global.by = global.By = protractor.By; (source - github.com/angular/protractor/commit/…)Necktie
How to find element by class and other means of non angular sites?Tankard
@EaswaramoorthyK by.className . Refer to docsUzzi
I
17

waitForAngular should now be used instead of the deprecated ignoreSynchronization property.

The following waitForAngular guidance is taken from the Protractor docs for timeouts:

How to disable waiting for Angular

If you need to navigate to a page which does not use Angular, you can turn off waiting for Angular by setting `browser.waitForAngularEnabled(false). For example:

browser.waitForAngularEnabled(false);
browser.get('/non-angular-login-page.html');

element(by.id('username')).sendKeys('Jane');
element(by.id('password')).sendKeys('1234');
element(by.id('clickme')).click();

browser.waitForAngularEnabled(true);
browser.get('/page-containing-angular.html');
Interesting answered 19/10, 2017 at 13:23 Comment(1)
its behaviour is buggyEuplastic
E
4

Forget about ignoreSynchronization!!! It no longer exists in protractor starting from protractor 5.3.0

browser.waitForAngularEnabled(false) should be used instead

Step by step instructions how to use it

Protractor has builtin handling of waiting for angular and this is what makes it different. However, if the page is not angular protractor will hang until it hits timeout error, so you need to disable that feature in order to test non-angular page. There is also an edge case, when the page is angular, but this feature will STILL make protractor error out. Perform the steps below, to find out when to disable protractor's waiting for angular

  1. Find out if your page is Angular: open dev console in the browser and inside of 'console' tab run command
getAllAngularTestabilities()

If the output is getAllAngularTestabilities is not defined, then your page is not angular, go to the last step to disable built-in waiting

  1. Run these commands in the console
getAllAngularTestabilities()[0]._ngZone.hasPendingMacrotasks
getAllAngularTestabilities()[0]._ngZone.hasPendingMicrotasks

If any of these return true (if there are micro or macro tasks pending), then go to the last step. If all are false, congrats, you can use the builtin protractor's waiting for angular. But if you don't like it as I don't, then read the last step to find out how to disable it

  1. Run the above mentioned command. BUT! It returns a promise, which needs to be handled, preferably using await keyword
await browser.waitForAngularEnabled(false)

This command can be ran anywhere: in the it block, in beforeAll, or in onPrepare of your configuration. Just make sure, if you use await to make the respective block async

beforeAll(async () => await browser.waitForAngularEnabled(false))
Ejectment answered 9/2, 2021 at 0:14 Comment(0)
M
3

To test on non angular site, you should remove the synchronisation. for that use the following:

browser.ignoreSynchronisation = true;
browser.get('url');
Muckraker answered 6/3, 2017 at 18:36 Comment(0)
R
2

In some occasions, to avoid errors need to add both values .

 browser.driver.ignoreSynchronization = true;
 browser.waitForAngularEnabled(false); 

You can add them in spec.js file .

describe('My first non angular class', function() {
    it ('My function', function() {
        browser.driver.ignoreSynchronization = true;
        browser.waitForAngularEnabled(false);

Or as @Mridul Suggested ,add them in config.js file .

exports.config = { directConnect: true, framework: 'jasmine',

  onPrepare: function () {
         browser.driver.ignoreSynchronization = true;// for non-angular set true. default value is false 
         browser.waitForAngularEnabled(false);   // for non-angular set false. default value is true  
       },
Rachelrachele answered 9/12, 2019 at 17:13 Comment(1)
In second approach assume that you only have none angular scripts.Rachelrachele
A
1

Personally, I didn't get any success with proposed solutions as the DOM elements weren't properly loaded in time.

I tried many ways of handling that asynchronous behavior, including browser.wait with browser.isElementPresent, but none of them were satisfying.

What did the trick is using Protractor returned Promises from its methods in onPrepare :

onPrepare: () => {

    browser.manage().window().maximize();

    browser.waitForAngularEnabled(true).then(function () {
        return browser.driver.get(baseUrl + '/auth/');
    }).then(function () {
        return browser.driver.findElement(by.name('login')).sendKeys('login');
    }).then(function () {
        return browser.driver.findElement(by.name('password')).sendKeys('password');
    }).then(function () {
        return browser.driver.findElement(by.name('submit')).click();
    }).then(function () {
        return true;
    });

    return browser.driver.wait(function () {
        return browser.driver.getCurrentUrl().then(function (url) {
            return /application/.test(url);
        });
    }, 10000);
},

I was inspired by https://github.com/angular/protractor/blob/master/spec/withLoginConf.js

Astroid answered 23/8, 2017 at 13:16 Comment(1)
Shouldn't it be browser.waitForAngularEnabled(false) instead of true?Semiyearly
B
1

add the below snippet in your .js spec file

beforeAll(function() {
    browser.waitForAngularEnabled(false);
});
Bradley answered 25/10, 2018 at 15:48 Comment(0)
G
1

Add the following piece of code in the conf.js file

   onPrepare: function () {
       browser.ignoreSynchronization = true;      
   }
Gwendagwendolen answered 12/11, 2019 at 9:37 Comment(0)
B
1

Add below snippet for non angular applications:

app- browser.ignoreSynchronization = true;
Butterfly answered 2/1, 2020 at 5:22 Comment(0)
B
0

Use below snippet in your config.js file for non-angular applications-

browser.ignoreSynchronization = true;

and for angular application -

browser.ignoreSynchronization = false;
Butterfly answered 14/5, 2020 at 11:53 Comment(0)
V
0

I am working on aurelia web-app which is a FE framework similar to Angular , React. In this I am using Protractor for automation.

Tech Stack which of my project:-

  • Protractor
  • Typescript
  • Page Object Modal
  • Cucumber
  • Chai
  • node
  • npm
  • VS Code (IDE)

The main change happens only in the configuration file, I can add code in github if that would help, here is the config file I am using in my project which works perfect for me. Posted some blogs as well in my wordpress , hope that can be of help.

const reporter = require('cucumber-html-reporter');
exports.config = {
    SELENIUM_PROMISE_MANAGER: false,
    directConnect: true,
    specs: ["./e2e/features/*/EndToEnd.feature"],
    format: 'json:cucumberReport.json',
    framework: 'custom',
    frameworkPath: require.resolve('protractor-cucumber-framework'),
    cucumberOpts: {
        strict: true,
        format: 'json:cucumberReport.json',
        keepAlive: false,
        require: [
            './e2e/hooks/*.ts',
            './e2e/stepDefinition/*/*.ts',
        ],
       tags: '@Regression'
    },
    beforeLaunch: function () {
        require('ts-node/register')
    },
    onPrepare: async () => {
        await browser.waitForAngularEnabled(false);
        await browser.ignoreSynchronization == true;
        await browser.manage().window().maximize();
        await browser.manage().timeouts().implicitlyWait(10000);
     },
    onComplete: async () => {
         var options = {
            theme: 'bootstrap',
            jsonFile: './reports/cucumberReport.json',
            output: './reports/cucumberReport.html',
            reportSuiteAsScenarios: true,
            launchReport: false,
            screenshotsDirectory: './reports/screenshots',
            storeScreenshots: true,
            metadata: {
                "Test Environment": "SAND-DEV-1",
                "Platform": "Windows 10",
            }
        };
        reporter.generate(options);
    },
};
Vanguard answered 27/5, 2020 at 9:11 Comment(0)
P
-5

Instead of Protractor, you can use for e2e testing the Testcafe.
Pros:

  • ES2016 syntax
  • no need an additional dependencies, configs and browser plugins
  • flexible selectors
  • easy setup
Peshawar answered 19/12, 2016 at 12:37 Comment(1)
dear @mlosev, this does not answer directly to the question. the question is "how to use protectrator..." and not "which library should I use instead of Protector" :-)Adham

© 2022 - 2024 — McMap. All rights reserved.