I've got an interesting setup here.
I have an Angular App that loads another Angular App inside an iframe. I'm interested in testing the iframed-in Angular app with Protractor.
Protractor is waiting for the first Angular app to load, but when I switch the iframe with
ptor.switchTo().frame('experience');
I can see that Protractor is not waiting for the iframed Angular app before making assertions. I have tried adding
ptor.waitForAngular();
After switching to the iframe with no luck. Anybody have any ideas what is going on here?
Thanks!
If it helps, I'm running my tests through the Saucelabs ssh tunnel on Chrome. I can tell that the tunneling is working because I see the resources for the iframed app being requested and downloading.
Testing iframes with protractor is a little bit tricky. It took me a while and a lot of patience to sort of understand what was going on. I hope this helps!
Protrator is built upon WebdriverJS, so you can use the whole package to test iframes. When you start testing with protractor, the first thing you do is get an instance of protractor:
var ptor = protractor.getInstance();
But to test what you have inside the iframe you will need ptor.driver instead of ptor!
var driver = ptor.driver;
Then, when you start writing the test, you find the iframe, you switch to it, you test it with 'driver' and you switch back to the initial frame.
ptor.switchTo().frame(driver.findElement(protractor.By.xpath('xpath-to-iframe')));
// Test iframe with driver
driver.findElement(protractor.By.xpath('some-sort-of-input')).sendKeys('username');
driver.findElement(protractor.By.xpath('other-sort-of-input')).sendKeys('password');
driver.findElement(protractor.By.xpath('other-sort-of-button')).click();
// Switch back to Default Content
ptor.switchTo().defaultContent();
// And WAIT for angular!!
ptor.waitForAngular();
The code that follows is a general example of what I mentioned above:
describe('Protractor iframe Test', function(){
var ptor, driver;
beforeEach(function(){
ptor = protractor.getInstance();
driver = ptor.driver;
});
it('should test the iframe', function(){
ptor.switchTo().frame(driver.findElement(protractor.By.xpath('xpath-to-iframe')));
// Test iframe with driver
driver.findElement(protractor.By.xpath('some-sort-of-input')).sendKeys('username');
driver.findElement(protractor.By.xpath('other-sort-of-input')).sendKeys('password');
driver.findElement(protractor.By.xpath('other-sort-of-button')).click();
// At this point, you can expect() things to happen to the iframe app
// Switch back to Default Content
ptor.switchTo().defaultContent();
// And WAIT for angular!!
ptor.waitForAngular();
// Then you can keep testing (or expecting something!)
expect('this answer').toBe('useful');
});
});
With protractor 2.5.1, #lthilon's answer was giving an 'Invalid Locator' error.
The following syntax resolved that though:
var driver = browser.driver;
var loc = by.tagName('iframe');
var el = driver.findElement(loc);
browser.switchTo().frame(el);
driver.findElement(by.tagName('body')).sendKeys('my test string');
browser.switchTo().defaultContent();
browser.waitForAngular();
Switching to an iframe is very simple according to latest protractor API docs 5.4.1:
await browser.switchTo().frame(element(by.xpath('//iframe')).getWebElement());
The context switches to the specified iframe, now every command that you run will be executed on the iframe. Now you can even switch to nested iframes. To switch back to parent iframe:
driver.switchTo().parentFrame();
Related
While running multiple test suits on CBT via jenkins parallel, Jenkins get slower and page takes more time to load on CBT and hence it shows below error(which is intermittent)
Error: Angular could not be found on the page Https:xxx.xyz.com If this is not an Angular application, you may need to turn off waiting for Angular.
If is not angular application, you need to turn of wait for angular. Usually login pages are not angular:
browser.waitForAngularEnabled(false);
To check if is angular, open dev tools and in console just write "angular", if page is angular will return object, if not will return "Uncaught ReferenceError: angular is not defined".
I have a web application build with Webpack. The application I created uses angularjs. When I usually load the application in Chrome and open developer tools, I usually find the source scripts under webpack:// -> . -> app/scripts in chrome dev tools.
I can find my controllers, services and all my script files there. I am now writing protractor tests for E2E on Chrome and am mocking the backend calls.
describe('signOnApp E2E test', function() {
beforeEach(function() {
browser.addMockModule('signOnApp', function() {
angular.module('signOnAppE2E', ['signOnApp', 'ngMockE2E'])
.run(function($httpBackend,$http) {
var dummyResponse = {"setting1": "value1",
"setting2": "value2"}
httpBackend.whenGET("/signOnApp/config/config.json").respond(200, dummyResponse);
});
});
});
it('should load the page after loading from config', function() {
browser.get('http://localhost:4321/signonApp.html');
browser.enterRepl();
});
})
When I run protractor test, I see that the page is loading and the call that I am making is not actually getting served by the mocked code. Hence I get a 404 error. Now when I open DevTools, I don't even see my code in sources. My angular app is manually bootstrapped and I did not use ng-app directive.
Am my missing something when I lookup my mocked code in chrome dev tools?
What I have: several integration test specs written in Jasmine for my AngularJS app (they navigate through my entire app)
What I want: perform a network monitoring of my app and export the data using HAR
Naive solution: just write a script which receives an URL and export the data using HAR. It's easy, but it's not automatic (I need to provide the urls manually)
Enhance solution: automate the process mentioned. A script that navigates through all the pages of my app and extracts the network data for each. But since I'm already navigating through all the pages of my app via integration tests (protractor + Jasmine) I want to just "plug-in" the part about exporting the network traffic.
I've found this How can I use BrowserMob Proxy with Protractor?, and I was checking out the example provided here example, but I'm not quite sure how it works.
What I should put as the host and port for the proxy?
I'm using Selenium, and I've specified the host and port for it, but I'm getting ECONNREFUSED errors.
This is my protractor file config:
var Proxy = require('browsermob-proxy').Proxy;
...
protractorConf = exports.base = {
//... more things
onPrepare: function() {
... more things....
browser.params.proxy = new Proxy({ // my selenium config for browsermob
selHost: '10.243.146.33',
selPort: 9456
});
//... more things
}
}
And in one of my integration tests specs (it's CoffeeScript btw):
beforeEach ->
browser.get BASE_URL
browser.params.proxy.doHAR 'some/page/of/my/app', (err, data) ->
if err
console.log err
else
console.log data
But I'm getting as I've said ECONNREFUSED error. I'm quite lost about the integration about Selenium with Protractor and brosermob.
Any ideas or alternatives? Thanks!
I am using protractor along with PhantomJs for e2e testing of my angular app.
Currently I am testing a login form. All the test work fine when I am simply checking
whether the form loaded correctly
username/password fields are empty
errors are displayed when you enter incorrect authentication information.
So far phantomJs and protractor have been quiet cooperative
However the below mentioned test cases simply fails all the time in protractor. I have tried various permutation and combinations but to no avail.
when the user enters correct authentication information in the login form, the angular app will change the route to dashboard section. i.e the url in the browser window would change from
http://localhost:12345/#/signin/
to
http://localhost:12345/#/dashboard
When I run the below give test, I know that the authentication was successful because the server logs display a success response object sent. Upon receiving this response, the angular app should have changed the route to /dashboard. However protractor fails to capture this change in route.
My test looks like below:
describe("SignOn Page - Performing authentication with valid credentials ",function(){
var ptor;
beforeEach(function(){
ptor = protractor.getInstance();
ptor.get('#/signon');
ptor.findElement(protractor.By.id('username')).sendKeys('joe');
ptor.findElement(protractor.By.id('password')).sendKeys('pass');
element(by.partialButtonText('Sign In')).click();
ptor.waitForAngular();
});
it("should re-direct user to dashboard page once the user enters correct authentication information",function(){
ptor = protractor.getInstance();
expect(ptor.getCurrentUrl()).toContain('dashboard');
expect(ptor.getTitle()).toContain('dashboard');
});
});
My question to this forum is, does protractor have issues changing states ? I am using ui.router in my angular application ?
I had the same issue because I was using phantomJS 1.9.x and not the 2.x
So you need to uninstall phantomjs 1.9
npm remove -g phantomjs
and install phantomJS 2.x
npm install -g phantomjs2
Hope it's also solve your issue
Is there any way to work around the fact that phantomjs and protractor don't work well together? (basically this issue here: https://github.com/detro/ghostdriver/issues/328)
What I want to do is to check before my test if the phantomjs browser has crashed (i.e. browser is not open.) If it has, I want to start a new instance of phantomjs and continue the rest of my tests (bonus if I can re-run the test that failed due to crash).
One approach that I haven't had success with looks like this:
var webdriver = require('selenium-webdriver');
var newDriver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.firefox()).
build();
var wrapper = protractor.wrapDriver(newDriver);
protractor.setInstance(wrapper);
ptor = protractor.getInstance();
driver = ptor.driver;
driver.get(URL);
Note that I need to open a non-angular page to start, hence the driver.get. In this case I can get another browser to open, but protractor doesn't hook onto it like I want to.
There may be a way to start fresh phantomjs instance after each test. Also they say that phantomjs 2.0 is much more stable then 1.9 version.
https://github.com/angular/protractor/issues/557
https://github.com/detro/ghostdriver/issues/328