I am using jasmine data provider to do data driven testing..I have the following code. The code executes but however, it enters undefined infront of the user names.. the same code works when I don't use any data provider and sendKeys("username"). Please advise. I have the need to use data driven. For my rest of my tests I have implemented parallel test Method.
describe('data driven tests', function() {
var EC = protractor.ExpectedConditions;
var using = require('jasmine-data-provider');
using([{val1: 'testUser1#1234.com'}, {val2: 'testUser2#1234.com'}], function (value)//changed here {
it('Should click on ', function() {
browser.get('/#/');
element(by.name('username')).sendKeys(value.val1, value.val2);
element(by.name('password')).clear().sendKeys('password');
element(by.id('login')).click();;
});
});
});
You can use the code below:
browser.executeScript("var editor = $('.CodeMirror')[0].CodeMirror;editor.setValue('{');");
Related
I am working on a code that has some unit test failing which I am trying to run. The unit test is
it('opens a confirmation dialog when deleting a layer and calls the delete wizard', function () {
var numLayers = scope.service.layers.length;
scope.deleteLayer({
serviceName: 'service1',
layerName: 'testLayer'
});
//Make sure confirmation dialog has been called
expect(bootbox.confirm).toHaveBeenCalled();
//the layer is NOT removed from the list
expect(scope.service.layers.length).toBe(numLayers);
});
I keep getting the error:
Unexpected request Get /api/configuration/utilities/userpreferences/f=json
I am trying to create a spyon for taking care of this api call. I am using this
spyOn(resourceFactory.configuration.utilities.userpreferences, 'get').and.callFake(function () { });
I have also defined this in the describe scope and injected in beforeeach
var resourceFactory = {
configuration: {
utilities: {
userpreferences: {
get: function () { }
}
}
}
};
The thing is I dont care about this call to API since I am not testing it.
When I use $httpBackend and do the following
/$httpBackend.whenGET("/api/configuration/utilities/userpreferences?f=json").respond({});
it works but I am not sure if this is the right way to do it. Especially since its not used anywhere else in the project.
Can you help with this.
I'm trying to use Protractor's addMockModule to insert mock data in my end-2-end test.
My test is supposed to go to a web site, find a button by css-class and click it. The button click calls the function dostuff() in MyService, which fetches data from the backend.
My code so far:
describe('should display validation error', function () {
it('should work', function () {
browser.get('http://my.url');
browser.addMockModule('MyService', function () {
// Fake Service Implementation returning a promise
angular.module('MyService', [])
.value({
dostuff: function () {
return {
then: function (callback) {
var data = { "foo": "bar" };
return callback(data);
}
};
}
});
});
var button = element(by.css('.btn-primary'));
button.click();
browser.sleep(5000);
});
});
The test is accessing the web site and clicking the button. The problem is that real data from the database is displayed, not the mock data.
I followed several threads, like this one: How to mock angular.module('myModule', []).value() in Jasmine/Protractor
However, it seems like the function protractor.getInstance() is deprecated.
Anyone got this working?
Take a look at the unit test for addMockModule(). Try to add the addMockModule statement before you call browser.get()
https://github.com/angular/protractor/blob/673d416b7ef5abd0953da940cfa8cf2a59650df4/spec/basic/mockmodule_spec.js
I have start to learning how to test properly on controller and encounter this following script.
http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html
it('should have a properly working VideosCtrl controller', inject(function($rootScope, $controller, $httpBackend) {
var searchTestAtr = 'cars';
var response = $httpBackend.expectJSONP(
'https://gdata.youtube.com/feeds/api/videos?q=' + searchTestAtr + '&v=2&alt=json&callback=JSON_CALLBACK');
response.respond(null);
var $scope = $rootScope.$new();
var ctrl = $controller('VideosCtrl', {
$scope : $scope,
$routeParams : {
q : searchTestAtr
}
});
}));
I am a bit confused... expectedJSON is in the following API page:
https://docs.angularjs.org/api/ngMock/service/$httpBackend
I am confused Just wondering what's testing in here, i can see the describe there but still lost... what's expected here?
This test has no explicit assertions, but it will fail if constructing the controller instance throws an exception for any reason.
Remember that if an assertion is failed, it throws an exception. Test runners just run your test function like so:
try {
runTest();
} catch (e) {
markTestFailed(e);
}
So if your test code throws an exception for any reason, the test will fail.
As with any unit test, you arrange act and then assert.
For the above test, the parts of arrange and act are self evident but the assert part may not be obvious. The test is just verifying that the search request was send when controller was created.
If you look at the controller code for video controller
$youtube.query($scope.q, true, function(q, videos) {
$scope.videos = videos;
$scope.onReady();
});
this can be confirmed.
The assertion part is done by the $httpBackend.expectJSONP. This setup tells karma to verify that a GET request is made to a specific url. The url here is the google search api with the search term cars.
The test basically sets up a mock backend and asserts that it was called.
I'm running E2E tests against an AngularJS site, using Karma and angular-scenario.
I'm executing some login code in a beforeEach function before every it block.
My login function has a timeout delay in it to ensure that the login completes correctly. This is time-consuming and inefficient (not to mention inelegant). In addition, the user would only login once during a session, so this would more accurately model my scenario.
What I'm looking for is a before function that executes the login only once for a collection of it blocks contained within a describe block, but this facility doesn't seem to exist (I've checked the docs and the source code).
Seems like an obvious requirement for a testing library! Has anybody solved this problem?
could you use a variable flag? for example:
var bdone = false;
describe('Search POC', function() {
beforeEach(function() {
if (!bdone) {
browser().navigateTo('login');
console.log('navigated once');
bdone = true;
}
});
it ('should have an img link on the login results', function() {
expect(element('a:last').html()).toMatch(/jpg/);
});
it ('should redirect to user details when clicked', function() {
element('#UserThumbImage:first').click();
expect(browser().window().href()).toMatch(/user/);
});
});
I'm trying to access $scope's within an E2E test without success...
As a test I tried this: (My site does not use JQuery..)
The runner has my site in a nested iframe, so I'm accessing it directly, then getting all ng-scopes and trying .scope() on them as in this post and code below...
var frameDocument = document.getElementById('test-frames').children[0].contentDocument;
var scopeElements = frameDocument.getElementsByClassName('ng-scope');
var scopes = [].map.call(scopeElements, function (e) {
return angular.element(e).scope();
});
The above code finds the proper elements, but calling scope() on them returns undefined for each....
Can someone confirm or deny that we can access the scope in E2E? I'd assume there is a way?
Thank-you
Here is my trick based on previous answer.
You can extend it to dynamic scopes. The main part is getting the reference to appWindow from addFutureAction.
//HTML CODE
<body id="main-controller" ng-controller="mainCtrl" ng-init="__init__()">
//Scenario helper.
/*
Run `callback` with scope from `selector`.
*/
angular.scenario.dsl('scope', function() {
return function(selector, callback) {
return this.addFutureAction(
'Executing scope at ' + selector,
function(appWindow, $document, done) {
var body = appWindow.document.getElementById(selector)
var scope = appWindow.angular.element(body).scope()
callback(scope)
scope.$apply()
done(null, 'OK');
})
}
})
//Actual test.
it(
'When alerts are defined, they are displayed.',
function() {
scope('main-controller', function(scope) {
scope.alerts.push({'type': 'error', 'msg': 'Some error.'})
})
expect(element('#alerts').css('display')).toEqual('block')
})
In E2E tests, accessing scope that way is not good option. Instead You can use helper functions like element() to select elements in page, and use expect() to check model data.
What you might need is unit testing. You can access $scope in unit tests easily.
There is a very good guide here: http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-testacular.html
Also it might be a timing issue, i can reach scopes in testacular runner like this. It runs tests in iframe. To make it work you need to add sleep(3) to your test. But this is very fragile.
setTimeout(function () {
console.log('try to reach frames');
var frame = window.frames[0].window.frames['senario_frame'];
if (!frame) {
console.log('too late');
} else {
var scopeElements = frame.document.getElementsByClassName('ng-scope');
var scopes = [].map.call(scopeElements, function (e) {
return frame.angular.element(e).scope();
});
console.log(scopes);
}
}, 2000);