рдореБрдЭреЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ 0.8 рдЪрд▓рд╛рддреЗ рд╕рдордп рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рд╣реИ рдФрд░ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд┐рдП рдЧрдП рд╣рдорд╛рд░реЗ рдРрдк рдкрд░ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рдкрд░реЗрд╢рд╛рдиреА рд╣реЛ рд░рд╣реА рд╣реИред
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рд╕реЗрдЯрдЕрдк рдХреЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рднрд╛рдЧреЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рд╕реНрдирд┐рдкреЗрдЯ рдпрд╣рд╛рдВ рджрд┐рдП рдЧрдП рд╣реИрдВ:
index.html:
<script type="text/javascript" data-main="js/main" src="js/libraries/require.js"></script>
рдЬреЗрдПрд╕/рдореЗрди.рдЬреЗрдПрд╕:
require({
shim: {
.... snip ..
}
},
['require', ..... ], function(require) {
return require(['bootstrap']);
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк.рдЬреЗрдПрд╕:
var appElm = $('html');
appElm.addClass('ng-app'); // this
angular.bootstrap(document, ['app']);
рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЛрдгреАрдп рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рдореИрдВ рдПрдЪрдЯреАрдПрдордПрд▓ рд╕реНрд░реЛрдд рджреЗрдЦрддрд╛ рд╣реВрдВ рддреЛ рдореИрдВ рдПрдЪрдЯреАрдПрдордПрд▓ рддрддреНрд╡ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реА рдПрдирдЬреА-рдРрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддрд╛ред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЪрд╛рдВрджрд╛ рднреА рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛ?
рдореИрдВ рдЪрд╛рдВрджрд╛ рдирдореВрдирд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЕрдкрдиреЗ рдРрдк рдХреЗ рдЕрдиреБрд░реВрдк рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реВрдВ:
specs: [
'../src/test/javascript/protractorSpec/*_spec.js',
],
baseUrl: 'http://localhost:8080/Viewer/',
rootElement: 'html',
рдирдореВрдирд╛ рдЬрд╛рдБрдЪ:
describe('List SMC Charts', function() {
var ptor= protractor.getInstance();
beforeEach(function() {
ptor.get('#/smcChart');
});
it('list, no filter', function() {
var selectOption = ptor.findElement(ptor.By.input("selectOption"));
});
});
рдЬрдм рдореИрдВ рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддрд╛ рд╣реВрдВ рддреЛ рджреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ:
1) List SMC Charts list, no filter
Message:
Error: Angular could not be found on the page http://localhost:8080/Viewer/#/smcChart
Stacktrace:
Error: Angular could not be found on the page http://localhost:8080/Viewer/#/smcChart
at /usr/local/lib/node_modules/protractor/lib/protractor.js:392:15
рддрдерд╛
2) List SMC Charts list, no filter
Message:
TypeError: Cannot call method 'input' of undefined
Stacktrace:
TypeError: Cannot call method 'input' of undefined
at null.<anonymous> (/Users/........//Viewer/src/test/javascript/protractorSpec/some_spec.js:9:55)
рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рдЧрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рддреНрд░реБрдЯрд┐ рднреА рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред рдореБрдЭреЗ рдРрд╕рд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рд▓рд╛рдЗрди: ptor.By.input рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред
рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?
рдХреНрдпрд╛ рдкреГрд╖реНрда рдкрд░ рдХреЛрдгреАрдп рдХреЛрдб рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╢рд┐рдо, рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдФрд░ рдЕрдиреНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди angular.min.js
рдирд╣реАрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
'app': {
deps: ['libraries/angular', 'libraries/angular-resource', 'libraries/angular-strap']
},
рдКрдкрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╕реНрдирд┐рдкреЗрдЯ рд╢рд┐рдо {} рддрддреНрд╡ рдХреЗ рдЕрдВрджрд░ рд░рд╣рддрд╛ рд╣реИ, рдореИрдВрдиреЗ рдЗрд╕реЗ рд╕реНрдирд┐рдкреЗрдЯ рд╕реЗ рдмрд╛рд╣рд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рдерд╛ред рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ angular.js рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
рдирдорд╕реНрддреЗ,
рд╣рд╛рдВ, рдкреНрд░реЛрдЯреИрдХреНрдЯрд░ рдХреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдПрдирдЬреА-рдРрдк рдХреА рдЙрдореНрдореАрдж рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХреА рдЧрдИ рд╕рд╛рдЗрдЯреЛрдВ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдЧреАред рдЗрд╕ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХреЗ рд▓рд┐рдП рдЬрд▓реНрдж рд╣реА рдПрдХ рдХрд╛рдордХрд╛рдЬ рдорд┐рд▓рдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИред
рдЕрдкрдбреЗрдЯ рдХреЗ рд▓рд┐рдП рдУрдХреЗ thxред рдЬрдм рдЖрдкрдХреЛ рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓ рдЧрдпрд╛ рддреЛ рдХреНрдпрд╛ рдЖрдк рдЙрд╕реЗ рдЗрд╕ рдЕрдВрдХ рдореЗрдВ рдкреЛрд╕реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдзреАрдореА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ - рдЖрдкрдХреЛ рдРрд╕рд╛ рдХрд░рдХреЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
describe('List SMC Charts', function() {
var ptor= protractor.getInstance();
beforeEach(function() {
ptor.driver.get('#/smcChart'); // Just use the plain old webdriver here, it won't complain if Angular isn't loaded yet.
});
it('list, no filter', function() {
var selectOption = ptor.findElement(ptor.By.input("selectOption"));
});
});
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдХрд╣реАрдВ ptor рд╡реИрд░рд┐рдПрдмрд▓ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ? рдЬреИрд╕реЗ var ptor = protractor.getInstance()
?
рдЗрд╕ рдкрд░ рдХрд┐рд╕реА рднреА рдЕрджреНрдпрддрди? рдЖрдкрдХрд╛ рд╕реБрдЭрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдорд╛рдзрд╛рди рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ (рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░@0.10.0, [email protected])
рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдЧреИрд░-рдХреЛрдгреАрдп рд▓реЙрдЧрд┐рди рд╕реНрдХреНрд░реАрди рдХрд╛ рдПрдХ рдЕрдЬреАрдм рд╕рдВрдпреЛрдЬрди рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдРрдк:
describe('User levels', function() {
var ptor, driver;
var findByName = function (name) {
return driver.findElement(protractor.By.name(name));
};
describe('Editors', function() {
ptor = protractor.getInstance();
driver = ptor.driver;
it('Can log in', function() {
driver.get('http://localhost:8000/');
findByName('login').sendKeys('test_editor');
findByName('pass').sendKeys('rubbish');
driver.findElement(protractor.By.css('button[type="submit"]')).click();
}, 20000);
it('Shows the homepage', function() {
var el = ptor.findElement(protractor.By.css('h1[field="pageTitle"]'));
expect(el.getText()).toEqual('Welcome to Home');
}, 30000);
});
});
рдФрд░ рдореЗрд░рд╛ main.js
:
require([
'angular',
'app'
], function (angular, app) {
'use strict';
var body = document.body, name = app.name;
body.setAttribute('ng-app', name);
body.setAttribute('id', 'ng-app');
angular.bootstrap(body, [name]);
});
рд▓реЙрдЧрд┐рди рднрд╛рдЧ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдореИрдВ UnknownError: javascript error: angular is not defined
рдХреЗ рд╕рд╛рде рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрд░рдХреНрд╖рд┐рдд рдкреГрд╖реНрда рд▓реЛрдб рд╣реЛрдиреЗ рдХрд╛ рдПрдХ рдлреНрд▓реИрд╢ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ рдкреГрд╖реНрда рдХреЛ driver.get('...')
рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ ptor.get('...')
рдХреЗ рд╕рд╛рде рдкреБрдирдГ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдХреБрдЫ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдХреЛрдИ рд╕рдВрдХреЗрдд/рд╕рд▓рд╛рд╣/рд╕реБрдзрд╛рд░ рдХреГрддрдЬреНрдЮрддрд╛рдкреВрд░реНрд╡рдХ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖред
@magnetized рдЖрдкрдХреЛ рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓реЙрдЧрд┐рди рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рдХрд┐рд╕реА рддрд░реАрдХреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдЖрдк рдкреГрд╖реНрда рдкрд░ рдХреЛрдгреАрдп рд▓реЛрдб рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ ptor.findElement рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рдЖрдкрдХрд╛ 'рд▓реЙрдЧ рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ' рд╕реНрдкреЗрдХ рдПрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдЖрдкрдХреЗ рдРрдк рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╢рд░реНрдд рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ - https://github.com/angular/protractor/blob/master/spec/login/viaConfigConf.js
@juliemr рдмреНрд░рд┐рд▓рд┐рдпрдВрдЯ, рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдореИрдВ рд╕рдордЭ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдЪрд╛рдВрджрд╛ "рдХреЛрдгреАрдп рд▓реЛрдб рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ" рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЛ рдХрд╡рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред
рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдзрдиреНрдпрд╡рд╛рджред
рдореЗрд░реЗ рдкрд╛рд╕ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд╣реА рд╕реЗрдЯрдЕрдк рд╣реИред @juliemr рдХреНрдпрд╛ рдЖрдк рдЕрдкрдирд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЖрдкрдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ? рдзрдиреНрдпрд╡рд╛рдж!
@jorgenfb рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдорддрд▓рдм рдЙрд╕ рдЯрд┐рдкреНрдкрдгреА рдХреЛ рдореБрдЭ рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ?
рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдПрдВрдЧреБрд▓рд░ рд░рд╛рдЙрдЯрд░ рдХреЗ рдмреВрдЯ рд╣реЛрдиреЗ рдФрд░ url рдХреЛ рдирдВрдЧреЗ '/' рд╕реЗ рдмрджрд▓рдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рдХрд┐ рд▓реЙрдЧрд┐рди рд╕рд┐рд╕реНрдЯрдо рдЖрдкрдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рд░реНрдЧ рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ - рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ '/#view'ред
рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдмрдирд╛рдпрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ:
var waitUntilLoaded = function() {
ptor.wait(function() {
return ptor.driver.getCurrentUrl().then(function(url) {
return /view/.test(url);
});
});
};
рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдпрд╛ рдирд╣реАрдВ, рдпрд╣ рдЖрдкрдХреЗ рд░реВрдЯрд┐рдВрдЧ рдХреЙрдиреНрдлрд┐рдЧрд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
@juliemr рдзрдиреНрдпрд╡рд╛рдж, рдПрдХ рдЖрдХрд░реНрд╖рдг рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ :)
рдореБрдЭреЗ рдПрдХ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рд╣реИ (SO рдкрд░ рдкрд╛рдпрд╛ рдЧрдпрд╛: http://stackoverflow.com/questions/19391813/protractor-fails-to-find-angular) рдкреНрд░реЛрдЯреИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдХреЛрдгреАрдп рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдХреЛрдгреАрдп рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд▓реЛрдб рдФрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реЛред рдХреНрдпрд╛ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рд╣реИ (рдХреЛрдгреАрдп рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд┐рдП рдмрд┐рдирд╛ рдкрд░реАрдХреНрд╖рдг) рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╣рдореЗрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдВрдЧреБрд▓рд░ рдРрдкреНрд╕ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдмрдирд╛рдП рдЬрд╛ рд░рд╣реЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЛ рд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореБрдЭреЗ рдпрд╣ рднреА рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рди рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
+1 рдмреЗрд╣рддрд░ рдХреЛрдгреАрдп рдореИрдиреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдкреНрд░рд▓реЗрдЦрди рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП
рдХреНрдпрд╛ рдпрд╣ рдЕрднреА рднреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ?
рдореИрдВ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╛рдкрд╕ рдЬрд╛рдиреЗ рдФрд░ рдпрд╣ рджреЗрдЦрдиреЗ рдХрд╛ рд╕рдордп рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреБрдЫ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рддрдм рд╕реЗ рд╕рдВрд╕реНрдХрд░рдг рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдмрдВрдж рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдмрд╣рд╕ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдХрднреА рднреА рдЦреЛрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдореИрдВрдиреЗ рдЖрдЬ рд╣реА рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рд╣рдорд╛рд░рд╛ рдРрдк рдЖрд╡рд╢реНрдпрдХрддрд╛.рдЬреЗрдПрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ... рдпрджрд┐ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ, рдПрдХ рдХреЗ рд▓рд┐рдП, рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИред :-)
рдпрд╣рд╛рдВ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ред рдХреЛрдгреАрдп рдРрдк рдХреЗ рдмрд╛рд╣рд░ рд▓реЙрдЧрд┐рди рдкреЗрдЬ рдХреЗ рд╕рд╛рде рдЖрд╡реЗрджрди рдорд┐рд▓рд╛ред рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рдорд╛рдзрд╛рди рдкреБрд░рд╛рдирд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИред рдЙрд╕ рддрд░рд╣ рдХреЗ рдкрд░рд┐рджреГрд╢реНрдп рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрджреНрдпрддрди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рдмрд╣реБрдд рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗред
@hankduan рд╣рд╛рдБ, рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИред
рдореИрдВ рдЕрднреА рдЗрд╕ рдореБрджреНрджреЗ рд╕реЗ рдЬреВрдЭ рд░рд╣рд╛ рд╣реВрдВред рдкреГрд╖реНрдарднреВрдорд┐ рд╕рдорд╛рди рд╣реИ: рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдмрдбрд╝рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ RequJS рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред
рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА window.name='NG_DEFER_BOOTSTRAP!';
& angular.resumeBootstrap()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдирд╛ рдРрдк рдЕрдкрдбреЗрдЯ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЕрднреА рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдпрд╣ рдХрд╣рд╛, рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИред рдЖрдЧреЗ рдХреА рдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ https://github.com/knalli/protractor-with-deferred-bootstrap рдкрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ
git clone https://github.com/knalli/protractor-with-deferred-bootstrap.git
cd protractor-with-deferred-bootstrap
npm install
npm run-script webdriver
(рд╕реЗрд▓реЗрдирд┐рдпрдо рд╕рд░реНрд╡рд░)npm run-script server
(рдПрдХ рдорд┐рдиреА AJS рдРрдк рдкрд░реЛрд╕рдиреЗ рд╡рд╛рд▓рд╛ рдбреЗрдореЛ рдРрдк рд╕рд░реНрд╡рд░)npm run-script e2e-test
(рдЪрд╛рдЪрд╛ рдЪрд▓рд╛рддрд╛ рд╣реИ...)рдкрд░рд┐рдгрд╛рдо рд╣реИ
Using the selenium server at http://localhost:4444/wd/hub
Login: Click
Login: Waiting...
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
The last active task was:
unknown
F
Failures:
рдХреЗ рдмрд╛рдж
UnknownError: unknown error: [ng:btstrpd] App Already Bootstrapped with this Element '
рдЖрдЦрд┐рд░реА рддреНрд░реБрдЯрд┐ рдереЛрдбрд╝реА рдЕрдЬреАрдм рд╣реИ рдФрд░ рд╢рд╛рдпрдж рднреНрд░рд╛рдордХ рднреА рд╣реИ: рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдЙрдореНрдореАрджреЗрдВ рдареАрдХ рдереАрдВ рдФрд░ рд╣рдо рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдХреНрдпрд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ) рд╕рдлрд▓ рд░рд╣рд╛ред
рдХреНрд░реЙрд╕рдЪреЗрдХ: рдЕрдЧрд░ рдореИрдВ рдореИрдиреБрдЕрд▓ рдХреЗ рд╕рд╛рде рдбреЗрдореЛ рдРрдк рдХреЛ рдЧреИрд░-рдЖрд╕реНрдердЧрд┐рдд рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реВрдВ (рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг no-deferred
рд╢рд╛рдЦрд╛ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИ), рддреЛ рдпрд╣ рд╕рдлрд▓ рд╣реЛрдЧрд╛ред
рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рддрдерд╛рдХрдерд┐рдд "рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб" рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ:
protractor.getInstance()
рдФрд░ ignoreSynchronization
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ -> рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВclientSideScripts.js/waitForAngular
-> рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВрдореИрдВрдиреЗ рдХрд▓ рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрд╛ рдерд╛ рдФрд░ рдирд▓реНрд▓реА рдЬреИрд╕реА рд╣реА рд╕рдорд╕реНрдпрд╛ рдереАред
@knali рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореИрдВ рдХреБрдЫ рджрд┐рдиреЛрдВ рдореЗрдВ рджреЗрдЦ рд▓реВрдВрдЧрд╛
рддреЛ рдореЗрд░рд╛ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рд╕рднреА рдХрд╛рдореЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реИ (рдПрдХ рд╡рд┐рдлрд▓рддрд╛ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд▓реЗрдХрд┐рди рдпрд╣ рдореЗрд░реА рдЧрд▓рддреА рд╣реИ :-P)ред
рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛/рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рдореЗрд░рд╛ рд╕реЗрдЯрдЕрдк рд╣реИ:
рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рд╕рдВрд╕реНрдХрд░рдг:
рд╕рдВрд╕реНрдХрд░рдг 1.0.0-рдЖрд░рд╕реА4
рд╕реЗрд▓реЗрдирд┐рдпрдо рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди:
рддрд╛рд░реАрдЦ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ
рдХреНрд░реЛрдордбреНрд░рд╛рдЗрд╡рд░:
рддрд╛рд░реАрдЦ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ
/*jshint expr: true*/
/*global browser: true*/
var TEST_DIR = '../tests/';
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub'
, specs : [ '../tests/e2e/_protractor.js' ]
, capabilities: {'browserName': 'chrome' }
, chromeDriver: './chromedriver' // <---- I remember not being able to get chromedriver working
// for some reason, so I just downloaded the executable and put it
// in my config directory
, onPrepare: function() {
"use strict";
browser.driver.get('http://localhost:5000/register');
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return /\#\/registration/.test(url);
});
});
}
// chromeOnly: true,
// baseUrl: 'http://localhost:5000/register'
, jasmineNodeOpts: {
showColors: true
}
};
/*jshint expr: true, undef: true */
/* global element: true, by: true, browser: true, model:true */
(function(){
"use strict";
var RegistrationPage = function(){
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return /\#\/registration/.test(url);
});
});
};
var account = new RegistrationPage();
account.elem = element.all(by.name('account_exists'));
account.accountNumber = element(by.name('account_number'));
account.submitAccountButton = element(by.css('#account_input button'));
account.selectHasAccount = function(){
account.elem.get(0).click();
return browser.getCurrentUrl();
};
account.enterAccountNumber = function(keys){
account.selectHasAccount().then(function(){
account.accountNumber.sendKeys(keys);
return account.submitAccountButton.click()
.then(function(){
return browser.getCurrentUrl();
});
//this wont log because already returned ^
// console.log('need to return again');
});
};
account.noAccount = function(){
account.elem.get(1).click();
};
describe('registration page', function() {
it("will survive", function(){
var registrationPage = new RegistrationPage()
, title = browser.getTitle();
expect(title).toBe('Web Shop | Homepage');
});
it('will change route on account_exists radiobox click', function(){
var elem = element.all(by.name('account_exists'))
, _url;
elem.get(0).click()
.then(function(){
_url = browser.getCurrentUrl().then(function(_url){
expect(_url).toBe('http://localhost:5000/register#/registration/has');
});
})
.then(function(){
elem.get(1).click().then(function(){
_url = browser.getCurrentUrl();
expect(_url).toBe('http://localhost:5000/register#/registration/no');
});
});
});
describe('navigate the hasAccount path:', function(){
it('will click hasAccount which will cause a route change.', function () {
expect(account.selectHasAccount()).toBe('http://localhost:5000/register#/registration/has');
});
it("will submit a valid account number", function(){
expect(account.enterAccountNumber('1231231231')).toBe('http://localhost:5000/register#/user');
});
});
it('will click noAccount which will cause a route change.', function () {
var _url;
account.noAccount();
_url = browser.getCurrentUrl();
expect(_url).toBe('http://localhost:5000/register#/registration/no');
});
});
})();
var pathToJQuery
if('querySelector' in document
&& 'localStorage' in window
&& 'addEventListener' in window) {
//ie9+ and all browsers
pathToJQuery = 'lib/jquery/dist/jquery'
} else {
//ie8 and ie7
pathToJQuery = 'lib/jquery-1.7.2.min'
}
requirejs.config({
paths : {
// Paths
"reg": 'js/registration'
, "com": 'js/common'
, "init": 'js/init'
, "regD": 'js/registration/directives'
, "regC": 'js/registration/controllers'
, "regS": 'js/registration/services'
, "regM": 'js/registration/modules'
//
// Frameworks
, "angular": "lib/angular/angular"
, "angular.animate" : "lib/angular-animate/angular-animate"
, "jquery": pathToJQuery //< = == v long story; don't judge me.
, "jqueryMigrate" : "lib/jquery-migrate/jquery-migrate"
, "mocks": "lib/angular-mocks/angular-mocks"
, "ui_router": "lib/angular-ui-router/release/angular-ui-router"
, "Q": "lib/q/q"
// Init
, "apps_init" : 'js/init/apps_init'
, "apps_bootstrap" : 'js/init/apps_bootstrap'
// , "jquery_bootstrap" : 'js/init/jquery_bootstrap'
, "registration": "js/init/registration"
// Common
// Registration
, "registration": "js/registration/registration"
// Controllers
, "account.controller" : 'js/registration/controllers/account.controller'
, "user.controller" : 'js/registration/controllers/user.controller'
// Directives
, "account.directive" : 'js/registration/directives/account.directive'
// Services
, "user.service" : "js/registration/services/user.service"
}
, shim: {
'angular': {
exports : 'angular'
}
, 'angular.animate' : {deps: ['angular']}
, 'jqueryMigrate' : {deps: ['jquery']}
, 'ui_router' : ['angular']
, 'mocks': { deps: ['angular'], 'exports': 'angular.mock' }
}
});
if( pathToJQuery === 'lib/jquery/dist/jquery' ){
requirejs([
'angular' , 'jquery' , 'jqueryMigrate', 'init/jquery_bootstrap', 'init/apps_bootstrap' ]
, function(angular, jquery, jquery_bootstrap, apps_bootstrap) {
}
);
} else {
requirejs([
'angular' , 'jquery' , 'jqueryMigrate', 'init/jquery_bootstrap', 'init/apps_bootstrap' ]
, function(angular, jquery, jqueryMigrate, jquery_bootstrap, apps_bootstrap) {
}
);
}
console.log("working");
<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org"
xmlns:fab="http://angularjs.org"
xmlns:ui ="http://angularjs.org"
lang = "en" class = "no-js" >
<head >
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta charset="utf-8">
<link rel="shortcut icon" type="image/x-icon" media="all" href="/images/favicon.ico" />
<script type="text/javascript" src="lib/modernizr.js"></script>
<!-- Default ie theme files:-->
<!--[if lte IE 9]><script type="text/javascript">console = {}; console.log = function(){};</script><![endif]-->
<!--[if IE 8]><link type="text/css" rel="stylesheet" href="build/css/ie8/theme.css" /><![endif]-->
<!--[if IE 7]><link type="text/css" rel="stylesheet" href="build/css/ie7/theme.css" /><![endif]-->
<!-- Normal styles -->
<link type="text/css" href="css/style.css" rel="stylesheet">
<!--[if IE 8]> <link type="text/css" rel="stylesheet" href="build/css/ie8/ie_8.css" /> <![endif]-->
<!--[if IE 7]> <link type="text/css" rel="stylesheet" href="build/css/ie7/lte_ie7.css"/> <link type="text/css" rel="stylesheet" href="build/css/ie7/ie_7.css" /><![endif]-->
<script data-main="main" src="lib/requirejs/require.js"></script>
</head >
<body class = "page-homepage language-en" >
<div id = "wrapper" >
<div id = "page" data-currency-iso-code = "USD" >
{{> _header}}
<a href = "#skip-to-content" class = "skiptocontent" >Skip to content</a >
<a href = "#skiptonavigation" class = "skiptonavigation" >Skip to navigation menu</a >
<!--[if lte IE 10]> <p class="browsehappy" style="margin-top: 10px; ">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p><![endif]-->
<main ng-cloak id = "content" role = "main" class = "page_main <!--[if IE7]>ng-cloak<![endif]-->" >
</main>
</div >
</div >
</body >
</html >
(function(){
"use strict";
// node requires
//==============================
// express-hbs
// express
//
const express = require('express')
, portN = 5000
, hbs = require('express-hbs')
, app = express()
, path = require('path')
, Server = require('./server')
, bodyParser = require('body-parser')
, serveStatic = require('serve-static')
, session = require('express-session')
, router = express.Router()
, logger = require('morgan')
, methodOverride = require('method-override')
, errorhandler = require('errorhandler')
// view paths
//==============================
//
//
//
, viewsD = __dirname + '/views/'
, partialsD = viewsD + 'partials/'
, layoutsD = viewsD + 'layouts/'
, testsD = __dirname + '/tests/'
, publicD = __dirname + '/public/'
, styleguideD = publicD+ '/styleguide/'
, defaultF = layoutsD + 'default.hbs';
// Express setup.
//==============================
//
//
//
app.use(express.static(publicD))
.use(bodyParser())
.use(logger('dev'))
.use(methodOverride())
.use(serveStatic(path.join(__dirname, 'public')))
.use(errorhandler());
app.set('view engine', 'hbs')
.set('port', process.env.PORT || portN)
.set('cache', false)
.set('views', viewsD);
app.engine('hbs', hbs.express3({
partialsDir: partialsD,
defaultLayout: defaultF,
layoutsDir: layoutsD
}));
var indx = {};
app.get( '/' ,function (req, res) {
res.render(partialsD + '_home.hbs', indx);
});
app.get( '/register' ,function (req, res) {
res.render(partialsD + '_register.hbs', indx);
});
new Server(app);
})();
module.exports = function(app){
"use strict";
var http = require('http');
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
};
module.exports = function (app) {
"use strict";
var http = require ('http');
http.createServer (app).listen (app.get ('port'),function () {
console.log ('Express server listening on port ' + app.get ('port'));
}).on ('error', function (e) {
console.log ("got error: " + e.message);
});
};
"dependencies": {
"body-parser": "^1.2.1",
"bower": "^1.3.2",
"errorhandler": "^1.0.1",
"express": "^4.3.1",
"express-hbs": "^0.7.9",
"express-session": "^1.2.0",
"node-dev": "^2.3.0"
},
"scripts": {
"start": "node --harmony $* ./node_modules/.bin/node-dev controller.js",
},
"devDependencies": {
"browserstack-webdriver": "^2.41.1",
"grunt-protractor-runner": "^1.0.0",
"method-override": "^1.0.2",
"morgan": "^1.1.1",
"protractor": "^0.23.1",
"requirejs": "^2.1.11",
"serve-static": "^1.1.0",
},
"author": "Andrew Luhring"
config/
protractor.config.js
chromedriver
server.js
controller.js
public/
main.js
js/
lib/
tests/
e2e/
_protractor.js <=== test file.
views/
layouts/
default.hbs
partials/
_head.hbs
_register.hbs <=== file being tested.
рдкреВрд░рд╛ рдпрдХреАрди рд╣реИ рдХрд┐ рдпрд╣ рдореЗрд░рд╛ рдкреВрд░рд╛ рд╕реЗрдЯрдЕрдк рд╣реИред рд▓рдЧрд╛ рдХрд┐ рдореИрдВ рд╡рд░реНрдмреЛрдЬрд╝ рдХреЗ рд▓рд┐рдП рдЬрд╛рдКрдВрдЧрд╛ред рдЙрдореНрдореАрдж рд╣реИ рдХреА рд╡реЛ рдорджрдж рдХрд░рджреЗред
рдореБрдЭреЗ рдЬреЛ рдХрд░рдирд╛ рдерд╛ рд╡рд╣ рдерд╛:
рджреЗрдЦреЗрдВ https://github.com/mikaraento/protractor-reuse/blob/master/index.js
рдХреНрдпрд╛ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдХреНрд░реЛрдо рдФрд░ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣рдореЗрд╢рд╛ рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдореЗрдВ рдХреНрдпреЛрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ?
рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡рд╣реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдиреНрдп рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛ рд░рд╣реА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдПрдХ рдЬреИрд╕реА рдирд╣реАрдВ рдЪрд▓ рд╕рдХрддреА рд╣реИрдВред рдореБрдЭреЗ рдмрд╛рд░-рдмрд╛рд░ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдорд┐рд▓ рд░рд╣реА рд╣реИрдВ рдЬреИрд╕реЗ рдЯрд╛рдЗрдо рдЖрдЙрдЯ рдЕрдкрд╡рд╛рдж:
рд╕рдВрджреЗрд╢: 'рд╕рдордп рд╕рдорд╛рдкреНрдд: 30000 рдорд┐рд╕реЗ рдХреЗ рдмрд╛рдж рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдХрд▓реНрдкрдирд╛ рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИтАЩ,
рдЯреНрд░реЗрд╕: тАЛтАЛ{рд╕реНрдЯреИрдХ: рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд}}]
рдФрд░ рдХрднреА-рдХрднреА рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓ рд░рд╣рд╛ рд╣реИред
рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореИрдВрдиреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ defaultTimeou tInterval:1000000 рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рд╣реИ, рдореЗрд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдореБрдЭреЗ рдЗрдВрдЯрд░рдиреЗрдЯ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп рдЙрдкрд░реНрдпреБрдХреНрдд рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдорд┐рд▓ рд░рд╣реА рд╣реИрдВ ...
рдХреНрдпрд╛ рдХреЛрдИ рдЗрд╕ рдкрд░ рдореЗрд░реА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ?
рд╕рд╛рджрд░,
рд╕рдВрддреЛрд╖ рдЪреБрдирдЪреБ
рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рд╣реИ? рдпрд╛ рдХреНрдпрд╛ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреНрд░реЛрдо рдФрд░ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд┐рдП рдЧрдП рдРрдкреНрд╕ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ?
@hankduan рдХреНрдпрд╛ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реА рд╣реИ? рд╢рд╛рдпрдж рд╣рдо рдХреБрдЫ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реАрдПрд▓ рдЖрдЙрдЯ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЯреИрдХреНрдЯрд░ рдХреЗ рд▓рд┐рдП рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ (https://github.com/angular/protractor/pull/1155)ред рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдХрдИ рдЕрдиреНрдп рдореБрджреНрджреЛрдВ рдХреЛ рдареАрдХ рдХрд░рдирд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдорджрдж)ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВрдиреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрднреА рднреА рдореИрдиреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рд┐рд░реНрдл рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд╣реИред
рдЗрд╕ рдкреАрдЖрд░ рдХреЛ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдФрд░ рдПрдВрдЧреБрд▓рд░ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдереЛрдбрд╝реЗ рд╕рдордп рдореЗрдВ рдЬрд╛рд░реА рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкреНрд░реЛрдЯреИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдПрдВрдЧреБрд▓рд░ рдХреЗ рддрд░реАрдХреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╢реАрд░реНрд╖ рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕рдорд╛рдзрд╛рди рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддрдиреА рд╣реА рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рд╣реИред рдпрд╣ рдЙрд╕ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдкрдХрд╛ рдкреВрд░рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдПрдХ рдХреЛрдгреАрдп рдРрдк рд╣реИ (рд▓реЙрдЧрд┐рди рдХреЗ рдмрд╛рдж рдПрдХ div рдкрд░ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдЬреИрд╕рд╛ рдХреБрдЫ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рддрд░рд╣)ред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдгреАрдп рд▓реЛрдб рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рддрдХ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рджреЗрд░реА рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдХреЛрдгреАрдп рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдЙрди рдХрд╛рдордХрд╛рдЬ рд╕реЗ рджреВрд░ рднрд╛рдЧрддрд╛ рд╣реВрдВ рдЬреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдордирд╛ рдХрд░рддреЗ рд╣реИрдВред
рдореИрдВ рдЧреНрд░рдВрдЯ рдЯреВ рдХреЙрдирдХреИрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ/рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдПрдХ рдЬреЗрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдиреАрдЪреЗ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреЗ рд╕рд╛рде index.html рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдПрдХрдорд╛рддреНрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реИред рдЪрд▓рд┐рдП рдЗрд╕реЗ script.js рдХрд╣рддреЗ рд╣реИрдВред рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рдореИрдВ рдПрдХ рдЕрд▓рдЧ рдЧреНрд░рдВрдЯ рдХрд╛рд░реНрдп рдЪрд▓рд╛рддрд╛ рд╣реВрдВ, рдЬреЛ рдХреИрд╢рд┐рдВрдЧ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ, рдЕрд╕реАрдорд┐рдд рд░реВрдк рд╕реЗ, рдФрд░ рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдХреЗ рд╕рд╛рде рд╢реЗрд╖ рдЬреЗрдПрд╕ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЬрдм рдореИрдВ рд╡рд┐рдХрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рддреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдпрд╣ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╕реЗрдЯ script.js рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ, рдореИрдВ рдХреЗрд╡рд▓ index.html рд╕реЗ script.js рд▓реЛрдб рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреЗ рд╕рд╛рдеред
рддреЛ, рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рдореБрдЭреЗ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдЖрд╕рд╛рди рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ рдореИрдВ рдкреНрд░реЛрдбрдХреНрд╢рди рдЬреЗрдПрд╕ рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдЬреЗрдПрд╕ рд▓реЛрдб рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдореИрдВ рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд▓реЛрдб рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реВрдВред
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк_рджреЗрд╡.рдЬреЗрдПрд╕
.element(document.body)
.ready(function() {
angular.bootstrap(document.body, ['App']);
});
рдЙрддреНрдкрд╛рджрди рдореЗрдВ, рдореИрдВ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЪрд╛рдВрджрд╛ рдЗрд╕реЗ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдореИрдВ рдЕрдкрдиреЗ рдкреНрд░реЛрдбрдХреНрд╢рди рдХреЛрдб рдХреЗ рдЦрд┐рд▓рд╛рдл рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдЪрд▓рд╛ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдПрдЪрдЯреАрдПрдордПрд▓ рд╕реЗ "рдПрдирдЬреА-рдРрдк" рд╡рд┐рд╢реЗрд╖рддрд╛ рднреА рд╣рдЯрд╛ рджреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдирд╣реАрдВ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдореИрдВ script.js рдореЗрдВ рдЕрдиреНрдп рд╕рднреА JS рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдбрд╛рд▓рдХрд░ рдкреНрд░реЛрдбрдХреНрд╢рди рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВред
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк_рдкреНрд░реЛрдб.рдЬреЗрдПрд╕
window.document.body.setAttribute("ng-app", "myApp");
рдмрд╕ "myApp" рдХреЛ рдЕрдкрдиреЗ рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓ рдХреЗ рдирд╛рдо рд╕реЗ рдмрджрд▓реЗрдВред
рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рдпрджрд┐ рдЖрдк рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЕрдкрдиреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдХреЗ рдЦрд┐рд▓рд╛рдл рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд╕рд╛рде рдареАрдХ рд╣реИрдВ (рдЬрд┐рд╕реЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдХреЛрдгреАрдп рд▓реЛрдб рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдмрд╕ рдПрдирдЬреА-рдРрдк рдирд┐рд░реНрджреЗрд╢ рдЬреЛрдбрд╝реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХрд░ рд╕рдХреЗред рдЕрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣реИ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рдЖрдкрдХреА рд╡рд┐рднрд┐рдиреНрди рд▓рд┐рдкрд┐рдпреЛрдВ рдХреА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓реЛрдбрд┐рдВрдЧ, рдФрд░ рдЖрдкрдХреЗ рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЯреИрдХреНрдЯрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ред
рдореЗрд░реЗ рд▓рд┐рдП рдЬреЛ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛, рд╡рд╣ рдореЗрд░реЗ protractor.conf.js рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝ рд░рд╣рд╛ рдерд╛:
onPrepare: function()
{
// implicit and page load timeouts
browser.manage().timeouts().pageLoadTimeout(40000);
browser.manage().timeouts().implicitlyWait(25000);
// for non-angular page
browser.ignoreSynchronization = true;
// sign in before all tests
}
рдЕрдЧрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ =]
рдЗрд╕реА рддрд░рд╣ рдХрд╛ рдореБрджреНрджрд╛ рдерд╛ред рдпрд╣ рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рдорд┐рд▓реА:
рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рдРрдк рдХреЛ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдХреИрд╕реЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдРрд╕рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ:
рдЗрд╕рд▓рд┐рдП рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХрд╛ рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рд░реЛрдз рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЛрдгреАрдп рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, angular.boostrap() рдпрд╛ angular.resumeBoostrap() рдкрд░ рджреВрд╕рд░реА рдХреЙрд▓ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдпрд╛ рдРрдк рдХреЛ рддреЛрдбрд╝ рджреЗрдЧреАред рддреЛ, рд╢рд░реАрд░ рдореЗрдВ рдПрдирдЬреА-рдРрдк рдХреА рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЖрдк angular.boostrap() рдХреЛ рд╕реНрд╡рдпрдВ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ NG_DEFER_BOOTSTRAP рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛! рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗред
рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд▓реЛрдбрд┐рдВрдЧ рдФрд░ рдмреВрдЯрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдХрд┐рд╕реА рднреА рдРрдк рдХреЛрдб рджреНрд╡рд╛рд░рд╛ window.name рдирд╣реАрдВ рдмрджрд▓рд╛ рдЧрдпрд╛ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ jQuery рдРрд╕рд╛ рдХрд░ рд░рд╣рд╛ рдерд╛, рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рдХрд┐ рдХреНрдпреЛрдВред рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛рдП рдЧрдП jQuery рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ред рдпрд╣реА рд╣реИ рд╕рдорд╕реНрдпрд╛ рдХреА рдЬрдбрд╝!
рдЕрднреА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЦреЛрдЬ рд░рд╣рд╛ рд╣реВрдВ, рдмрд┐рдирд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рддреЛрдбрд╝реЗ jQuery рдХреЛ рдХреИрд╕реЗ рд╡рд╛рдкрд╕ рд▓рд╛рдпрд╛ рдЬрд╛рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ!
рдЖрдЦрд┐рд░рдХрд╛рд░,
рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдПрдХ рдкреГрд╖реНрда рдкрд░ jQuery рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдереА (рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдмрд╛рд╣рд░реА рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)ред рдЗрд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдФрд░ рдХреЗрд╡рд▓ рд╣рдорд╛рд░реЗ jQuery рдХреЛ рдкреГрд╖реНрда рдкрд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдФрд░ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдХреБрдЫ рдХреЛрдб, рд╕рд╣рд╛рдпрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
index.html
<body>
...
<script data-main="require.conf" type="text/javascript" src="bower_components/requirejs/require.js"></script>
</body>
рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдБ рд╡рд┐рдиреНрдпрд╛рд╕
...
deps: ["proto/main"],
...
рдкреНрд░реЛрдЯреЛ.рдЬреЗрдПрд╕
// We just load deps and register the module:
define(["deps"],function(){
angular.module('proto'...
}
рдкреНрд░реЛрдЯреЛ/рдореЗрди.рдЬреЗрдПрд╕
define(["require", "exports", "proto", "angular"],
function (require, exports) {
angular.bootstrap(document, ['proto']);
});
рдФрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг рдпреБрдХреНрддрд┐
var protractor = require('protractor');
var ptor;
function prepareBrowser() {
ptor = protractor.getInstance();
return ptor.get(ptor["baseUrl"] + '/login').then(function () {
console.log("got");
return ptor.waitForAngular().then(function () {
console.log("ngwaited");
});
});
}
describe('container', function () {
beforeEach(function () {
return prepareBrowser();
});
describe('form tests', function () {
it('form is shown', function () {
expect($('[ng-controller=LoginContr]').isDisplayed()).toBeTruthy();
});
});
});
рдЙрддреНрдкрд╛рджрди
Using the selenium server at http://localhost:4444/wd/hub
got
ngwaited
container
form tests
form is shown - pass
Finished in 3.112 seconds
1 test, 1 assertion, 0 failures
рд╣реЛрд░реЗ!
рдЬрдм рд╣рдордиреЗ ng-app
рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ angular.bootstrap()
#$ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛, рддреЛ projotractor.conf рдореЗрдВ rootElement: 'div'
рдЬреЛрдбрд╝рдирд╛ рд╣реА рдПрдХрдорд╛рддреНрд░ рдмрджрд▓рд╛рд╡ рдерд╛ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рдВрджрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рд╣рдо рдХреЛрдгреАрдп 1.3.0 рдФрд░ рдЪрд╛рдВрджрд╛ 1.3.1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред
@jongunnip рд╣рд╛рдБ рдЬреЛ рдореЗрд░реЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!
@mikaraento рдЗрд╕рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛, рдзрдиреНрдпрд╡рд╛рдж ~
рд╣рд╛рдп рджреЛрд╕реНрддреЛрдВ, рдЗрд╕ рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЕрдЬреАрдм рдмрд╛рдд рд╣реИред
рдореЗрд░реЗ рдкрд╛рд╕ рдирд┐рдпрдорд┐рдд рдХреЛрдгреАрдп рдРрдк рд╣реИ - рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдпрд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ, рдореИрдВ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ 2.0.0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред
рдЬрдм рдореИрдВ рд╕реНрдЯреЗрдЬрд┐рдВрдЧ рдкрд░реНрдпрд╛рд╡рд░рдг рдкрд░ рд╕рд┐рд╕реНрдЯрдо рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЬрдм рдореИрдВ рдЗрд╕реЗ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдЪрд▓рд╛рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдореБрдЭреЗ рджреЗрддрд╛ рд╣реИ:
org.openqa.selenium.WebDriverException: unknown error: [ng:btstrpd] App Already Bootstrapped with this Element
... рд╕рдВрджреЗрд╢
рдЬрдм рдореИрдВ grunt:server
рдХреЗ рдмрдЬрд╛рдп рд╕реНрдерд┐рд░ рд╕рдВрд╕рд╛рдзрди рдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ Nginx рд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рд╕рдмрдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ рдЕрдЧрд░ рдореИрдВ рдЗрд╕реЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд▓рд╛рдЗрд╡рд░реЗрд▓реЛрдб рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рддрд╛ рд╣реВрдВ?
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдерд┐рд░ рд╕рд░реНрд╡рд░ рдЕрд▓рдЧ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЧреНрд░рдВрдЯ рдХреБрдЫ 404 рдпрд╛ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреА рд╕реЗрд╡рд╛ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдкрд╛рдЧрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдирдорд╕реНрддреЗ,
рдмрд╣реБрдд рд╕рдордп рдкрдврд╝рдиреЗ рдФрд░ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛ рдЬреЛ рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ( рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдирд┐рд╖реНрдкрд╛рджрди рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдареАрдХ рдХрд░реЗрдВ )
?protractor-test
рдЬреЛрдбрд╝реЗрдВ ( рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛрдб )if(location.href.indexOf("protractor-test") < 0){
// start angular app
angular.bootstrap(document, [module.name]);
} else {
// start angular app to protractor tests
window.name = 'NG_DEFER_BOOTSTRAP!' + window.name;
angular.bootstrap(document, [module.name]);
}
рдФрд░ рдЕрдВрдд рдореЗрдВ рд╕рднреА рдлрд┐рд░ рд╕реЗ рдХрд╛рдо рдкрд░ рд▓реМрдЯ рдЖрдП \o/
рдХреЙрдкреА рдХреЗ рд╕рд╛рде @juliemr
рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ (рд╕рд┐рд░реНрдл 1-2 рд╕рдкреНрддрд╛рд╣) рдЕрдкрдиреЗ рдХреЛрдгреАрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдореЗрд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рд▓реЙрдЧрд┐рди рдкреЗрдЬ рдкрд░ рдмреЙрдбреА рдЯреИрдЧ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдПрдирдЬреА-рдРрдк рд╣реИред рдореЗрд░рд╛ рдЯреЗрд╕реНрдЯ рдпрд╣ рдХрд╣рддреЗ рд╣реБрдП рд╢рд┐рдХрд╛рдпрдд рдХрд░рддрд╛ рд░рд╣рддрд╛ рд╣реИ рдХрд┐ "рдкреГрд╖реНрда рдкрд░ рдХреЛрдгреАрдп рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: // (рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрддрд╛): рдХреЛрдгреАрдп рдиреЗ рдХрднреА рднреА рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛рдмреВрдЯрд╕реНрдЯреНрд░реИрдк" рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рдареАрдХ рд╣реИред рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ (рдпрджрд┐ рдореИрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЗрдЧреНрдиреЛрд░рд╕рд┐рдВрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдЪрд╛рд▓реВ рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдареАрдХ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд╣реА рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ), рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдЬреВрд▓рд┐рдорд░ рдХреНрдпрд╛ рд╕реБрдЭрд╛рд╡ рджреЗ рд░рд╣рд╛ рд╣реИ (рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд░рд╛рд╕рдд рдбреНрд░рд╛рдЗрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ), рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдРрдк рд╢рд┐рдХрд╛рдпрдд рдХреНрдпреЛрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ рднрд▓реЗ рд╣реА рдЗрд╕рдореЗрдВ рдмреЙрдбреА рдЯреИрдЧ рдореЗрдВ рдПрдирдЬреА-рдРрдк рд╣реЛред рдРрдк рдлрдВрдХреНрд╢рдирд▓ рдмрд┐рд╣реЗрд╡рд┐рдпрд░ рдЗрд╕ рддрд░рд╣ рд╣реИ.. рд▓реЙрдЧ рдЗрди рдкреЗрдЬ..рд▓реЙрдЧ рдЗрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛрдо рдкреЗрдЬ рдкрд░ рдХрд┐рд╕реА рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ рдФрд░ рдпрд╣ рдПрдХ рдФрд░ рд╡рд┐рдВрдбреЛ / рдЯреИрдм рдЦреЛрд▓рддрд╛ рд╣реИред рдХреНрдпрд╛ рдХреЛрдИ рдореБрдЭреЗ рдЙрди рдЪрд░рдгреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддрд░реАрдХреЗ рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ (рдмреЙрдбреА рдЯреИрдЧ рдореЗрдВ рдПрдХ рдПрдирдЬреА-рдРрдк рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ)? рдХреНрдпрд╛ рдореБрдЭреЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк.рдЬреЗрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреБрдЫ рдЬрд╛рдБрдЪрдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ (рдореБрдЭреЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдИ рдПрдирдЬреА-рдРрдк рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред рдзрдиреНрдпрд╡рд╛рдж
рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рд╣реИ? рдПрдХ рдХреЛрдгреАрдп рдРрдк рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рдпрд╛ рддрд░реАрдХреЗ рдХреНрдпрд╛ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдПрдирдЬреА-рдРрдк рдирд╣реАрдВ рд╣реИ? @erkobridee рдХреНрдпрд╛ рдЖрдк рдЕрдкрдирд╛ рдЙрджрд╛рд╣рд░рдг рдЖрдЧреЗ рд╕рдордЭрд╛ рд╕рдХрддреЗ рд╣реИрдВ? рдФрд░ рдХреНрдпрд╛ рдХреЛрдИ рд╕рдордЭрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдгреАрдп рд▓реЛрдб рд╣реЛрдиреЗ рдкрд░ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЛ рдХреИрд╕реЗ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ window.name рдХреЛ рдареАрдХ рд╕реЗ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛ рд╣реИ?
@juliemr рдХреЛрдгреАрдп 1.5 рдХреЗ рд╕рд╛рде, рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд╛ рдкрд╕рдВрджреАрджрд╛ рддрд░реАрдХрд╛ рд╣реИред рдХреНрдпрд╛ рд░рд╛рд╕реНрддреЗ рдореЗрдВ рдзрдиреНрдп рдЪрд╛рдВрджрд╛ рдХрд╛ рд╕рдорд░реНрдерди рд╣реИ?
+1 рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЙрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдореИрдиреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рд▓рд╛рдн рдирд╣реАрдВ рд╣реИред рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдкрд░ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреВрд░рд╛ рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЛрдгреАрдп рд╕рд┐рдВрдХ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред
рдореЗрд░реЗ рд╕рд╛рде рднреА рд╡рд╣реА рджрд┐рдХреНрдХрдд рд╣реИред рдХрд┐рд╕реА рднреА рдЕрджреНрдпрддрди?
рдирдорд╕реНрддреЗ, рдХреНрдпрд╛ рдЗрд╕реЗ рд╕реБрдзрд╛рд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдпреЛрдЬрдирд╛ рдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ?
рдЕрдЬреАрдм рдХреЛрдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рдПрдирдЬреА-рдРрдк рдЧрд╛рдпрдм рдРрдкреНрд╕ рд╣реИрдВ рдФрд░ рдореИрдВ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛
рдЙрдиреНрд╣реЗрдВ рдЪрд╛рдВрджрд╛ рдХреЗ рд╕рд╛рде
16 рдЬреБрд▓рд╛рдИ 2016 рдХреЛ рд╕реБрдмрд╣ 5:01 рдмрдЬреЗ, "рдорд┐рд▓рд░рд╡рдХреНрд╕" рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:
рдирдорд╕реНрддреЗ, рдХреНрдпрд╛ рдЗрд╕реЗ рд╕реБрдзрд╛рд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдпреЛрдЬрдирд╛ рдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ?
-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдиреЗ рдЯрд┐рдкреНрдкрдгреА рдХреА рдереАред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/angular/protractor/issues/66#issuecomment -233104701,
рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AOghFs2ff0e-88DLafNGD3iCH8uCOgVaks5qWEmIgaJpZM4A82d7
.
2016 рдореЗрдВ рдЖрдЬ рддрдХ, рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдЕрднреА рднреА рдПрдХ рд╕рдорд╕реНрдпрд╛ рдереАред рдореИрдВрдиреЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪреБрдВрдмрдХреАрдп рдЙрддреНрддрд░ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд┐рдпрд╛ред рдореИрдВрдиреЗ рдЕрднреА рдХреБрдЫ рдмрджрд▓рд╛рд╡ рдХрд┐рдП рд╣реИрдВред рдХреНрдпрд╛ рдЕрдЪреНрдЫрд╛ рд╣реИ рдФрд░ рдмрд╛рддрдЪреАрдд рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдФрд░ рдЕрдкрдиреЗ рдРрдк рдХреЗ рдЕрдВрджрд░ рд╡рд╛рдкрд╕ рдЖрдирд╛ рд╣реИред *рдореИрдВрдиреЗ рдЗрд╕реЗ рдмреИрдмреЗрд▓ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп ES5 рдореЗрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред
рд╡рд░реНрдгрди рдХрд░реЗрдВ ('рд▓реЙрдЧрд┐рди рд╕реНрдХреНрд░реАрди', () => {
var urlTimeout = 9000;
const waitForUrlRegex = (regex, urlMatcher )=>{
return driver.wait(()=>{
return driver.getCurrentUrl().then( (url)=>{
return regex.test(url);
});
}, urlTimeout, "Expectation error: Timeout for url not matching " + urlMatcher );
};
const waitForRoute = (route)=>{
return waitForUrlRegex( new RegExp( route + "$" ), route );
}
const waitForUrl = (url)=>{
return waitForUrlRegex( new RegExp( "^https?:\/\/" + url ), url );
}
it('should go to homepage and click login button', ()=>{
driver.get( app_url, urlTimeout);
//there is a redirect to welcome route
expect( waitForRoute("welcome") ).toBe(true);
const loginButton = element.all(by.className("login_button")).get(0);
loginButton.click();
});
it( 'should enter credentials', ()=>{
expect( waitForUrl( non_angular_login_url ) ).toBe(true);
driver.findElement( by.name("user")).sendKeys( "username");
driver.findElement( by.name("password")).sendKeys( "userpassword");
driver.findElement( by.tagName("button")).click();
});
it( 'should go back to app, and continue testing', ()=>{
expect( waitForRoute( "user-screen") ).toBe(true);
});
});`
config.onрддреИрдпрд╛рд░ рдХрд░реЗрдВ
onPrepare: ()=>{
require("babel-register");
global.driver = browser.driver;
}
рдпрджрд┐ рдЖрдк рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдирд╣реАрдВ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдмрд╕ рдбреНрд░рд╛рдЗрд╡рд░ рдХреЛ рд╕реЛрдПрдВ рдФрд░ рдлрд┐рд░ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред
`driver.get(app_url+ "/#/welcome", urlTimeout);
driver.sleep( 1000 );
const loginButton = element.all(by.className("login_button")).get(0);
loginButton.click();`
рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдкреБрд░рд╛рдиреА рд╣реИред рдПрдХ рдмрд╛рд░ рдЬрдм рд╣рдо https://github.com/angular/protractor/issues/3857 рдХреЛ рднреА рд╕рдВрднрд╛рд▓ рд▓реЗрдВрдЧреЗ рддреЛ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдФрд░ рднреА рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реЛ рдЬрд╛рдПрдЧреАред
@sjelin рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ? рдореБрдЭреЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ 5.0 рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣реА рд╣реИред
рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп рдореБрдЭреЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝ рд░рд╣рд╛ рдерд╛ред рдФрд░ рдШреБрд░рдШреБрд░рд╛рд╣рдЯ рдХреЗ рд╕рд╛рде рдЪрд▓рдиреЗ рдХрд╛ рд╣рд▓ рдвреВрдВрдв рд▓рд┐рдпрд╛ред
рдкреНрд░рдпреБрдХреНрдд рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ рд╕рдВрд╕реНрдХрд░рдг 2.5.1ред
grunt.initConfig({
protractor: {
options: {
configFile: "protractor.conf.js", // Default protractor config file
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false, // If true, protractor will not use colors in its output.
args: {
// Arguments passed to the command
}
},
e2e: {
options: {
// Stops Grunt process if a test fails
keepAlive: true
}
}
}
})
npm install grunt-protractor-runner --save-dev
рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ рдФрд░ рд▓реЛрдб рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝реЗрдВ grunt.loadNpmTasks('grunt-protractor-runner')
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрджреЗрд╢ рдХреЗ рд╕рд╛рде рдЪрд╛рдВрджрд╛ рдЪрд▓рд╛рдПрдБ:
grunt protractor
рдпрд╛ рд╕реБрдЗрдЯ рдирд╛рдо рдХреЗ рд╕рд╛рде
grunt protractor --suite suite_name
рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред
browser.ignoreрд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди = рд╕рдЪ;
рдмреНрд░рд╛рдЙрдЬрд░.рдЧреЗрдЯ (рдпреВрдЖрд░рдПрд▓);
browser.ignoreрд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди = рдЭреВрдард╛;
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@sjelin рдореИрдиреНрдпреБрдЕрд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ? рдореБрдЭреЗ рдкреНрд░реЛрдЯреНрд░реИрдХреНрдЯрд░ 5.0 рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣реА рд╣реИред