Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit 77525af

Browse files
authored
feat(browser): chain promises in browser.get (#4017)
Closes #3904
1 parent 665a05e commit 77525af

File tree

1 file changed

+125
-117
lines changed

1 file changed

+125
-117
lines changed

Diff for: lib/browser.ts

+125-117
Original file line numberDiff line numberDiff line change
@@ -890,131 +890,139 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
890890
get(destination: string, timeout = this.getPageTimeout) {
891891
destination = this.baseUrl.indexOf('file://') === 0 ? this.baseUrl + destination :
892892
url.resolve(this.baseUrl, destination);
893-
let msg = (str: string) => {
894-
return 'Protractor.get(' + destination + ') - ' + str;
895-
};
896-
897-
if (this.bpClient) {
898-
this.driver.controlFlow().execute(() => {
899-
return this.bpClient.setSynchronization(false);
900-
});
901-
}
902893

903894
if (this.ignoreSynchronization) {
904-
this.driver.get(destination);
905-
return this.driver.controlFlow().execute(() => this.plugins_.onPageLoad()).then(() => {});
895+
return this.driver.get(destination)
896+
.then(() => this.driver.controlFlow().execute(() => this.plugins_.onPageLoad()))
897+
.then(() => null);
906898
}
907899

908-
let deferred = wdpromise.defer<void>();
909-
910-
this.driver.get(this.resetUrl).then(null, deferred.reject);
911-
this.executeScriptWithDescription(
912-
'window.name = "' + DEFER_LABEL + '" + window.name;' +
913-
'window.location.replace("' + destination + '");',
914-
msg('reset url'))
915-
.then(null, deferred.reject);
916-
917-
// We need to make sure the new url has loaded before
918-
// we try to execute any asynchronous scripts.
919-
this.driver
920-
.wait(
921-
() => {
922-
return this
923-
.executeScriptWithDescription('return window.location.href;', msg('get url'))
924-
.then(
925-
(url: any) => {
926-
return url !== this.resetUrl;
927-
},
928-
(err: IError) => {
929-
if (err.code == 13) {
930-
// Ignore the error, and continue trying. This is
931-
// because IE driver sometimes (~1%) will throw an
932-
// unknown error from this execution. See
933-
// https://github.com/angular/protractor/issues/841
934-
// This shouldn't mask errors because it will fail
935-
// with the timeout anyway.
936-
return false;
937-
} else {
938-
throw err;
939-
}
940-
});
941-
},
942-
timeout, 'waiting for page to load for ' + timeout + 'ms')
943-
.then(null, deferred.reject);
944-
945-
this.driver.controlFlow().execute(() => {
946-
return this.plugins_.onPageLoad();
947-
});
900+
let msg = (str: string) => {
901+
return 'Protractor.get(' + destination + ') - ' + str;
902+
};
948903

949-
// Make sure the page is an Angular page.
950-
this.executeAsyncScript_(
951-
clientSideScripts.testForAngular, msg('test for angular'), Math.floor(timeout / 1000),
952-
this.ng12Hybrid)
953-
.then(
954-
(angularTestResult: {ver: number, message: string}) => {
955-
let angularVersion = angularTestResult.ver;
956-
if (!angularVersion) {
957-
let message = angularTestResult.message;
958-
logger.error(`Could not find Angular on page ${destination} : ${message}`);
959-
throw new Error(
960-
`Angular could not be found on the page ${destination}. If this is not an ` +
961-
`Angular application, you may need to turn off waiting for Angular. Please ` +
962-
`see https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load`);
963-
}
964-
return angularVersion;
965-
},
966-
(err: Error) => {
967-
throw new Error('Error while running testForAngular: ' + err.message);
968-
})
969-
.then(loadMocks, deferred.reject);
970-
971-
let self = this;
972-
function loadMocks(angularVersion: number) {
973-
if (angularVersion === 1) {
974-
// At this point, Angular will pause for us until angular.resumeBootstrap is called.
975-
let moduleNames: string[] = [];
976-
for (const {name, script, args} of self.mockModules_) {
977-
moduleNames.push(name);
978-
let executeScriptArgs = [script, msg('add mock module ' + name), ...args];
979-
self.executeScriptWithDescription.apply(self, executeScriptArgs)
904+
return this.driver.controlFlow()
905+
.execute(() => {
906+
return wdpromise.when(null);
907+
})
908+
.then(() => {
909+
if (this.bpClient) {
910+
return this.driver.controlFlow().execute(() => {
911+
return this.bpClient.setSynchronization(false);
912+
});
913+
}
914+
})
915+
.then(() => {
916+
// Go to reset url
917+
return this.driver.get(this.resetUrl);
918+
})
919+
.then(() => {
920+
// Set defer label and navigate
921+
return this.executeScriptWithDescription(
922+
'window.name = "' + DEFER_LABEL + '" + window.name;' +
923+
'window.location.replace("' + destination + '");',
924+
msg('reset url'));
925+
})
926+
.then(() => {
927+
// We need to make sure the new url has loaded before
928+
// we try to execute any asynchronous scripts.
929+
return this.driver.wait(() => {
930+
return this.executeScriptWithDescription('return window.location.href;', msg('get url'))
931+
.then(
932+
(url: any) => {
933+
return url !== this.resetUrl;
934+
},
935+
(err: IError) => {
936+
if (err.code == 13) {
937+
// Ignore the error, and continue trying. This is
938+
// because IE driver sometimes (~1%) will throw an
939+
// unknown error from this execution. See
940+
// https://github.com/angular/protractor/issues/841
941+
// This shouldn't mask errors because it will fail
942+
// with the timeout anyway.
943+
return false;
944+
} else {
945+
throw err;
946+
}
947+
});
948+
}, timeout, 'waiting for page to load for ' + timeout + 'ms');
949+
})
950+
.then(() => {
951+
// Run Plugins
952+
return this.driver.controlFlow().execute(() => {
953+
return this.plugins_.onPageLoad();
954+
});
955+
})
956+
.then(() => {
957+
// Make sure the page is an Angular page.
958+
return this
959+
.executeAsyncScript_(
960+
clientSideScripts.testForAngular, msg('test for angular'),
961+
Math.floor(timeout / 1000), this.ng12Hybrid)
980962
.then(
981-
null,
963+
(angularTestResult: {ver: number, message: string}) => {
964+
let angularVersion = angularTestResult.ver;
965+
if (!angularVersion) {
966+
let message = angularTestResult.message;
967+
logger.error(`Could not find Angular on page ${destination} : ${message}`);
968+
throw new Error(
969+
'Angular could not be found on the page ${destination}.' +
970+
`If this is not an Angular application, you may need to turn off waiting for Angular.
971+
Please see
972+
https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load`);
973+
}
974+
return angularVersion;
975+
},
982976
(err: Error) => {
983-
throw new Error(
984-
'Error while running module script ' + name + ': ' + err.message);
985-
})
986-
.then(null, deferred.reject);
987-
}
988-
989-
self.executeScriptWithDescription(
990-
'window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = ' +
991-
'angular.resumeBootstrap(arguments[0]);',
992-
msg('resume bootstrap'), moduleNames)
993-
.then(null, deferred.reject);
994-
} else {
995-
// TODO: support mock modules in Angular2. For now, error if someone
996-
// has tried to use one.
997-
if (self.mockModules_.length > 1) {
998-
deferred.reject(
999-
'Trying to load mock modules on an Angular2 app ' +
1000-
'is not yet supported.');
1001-
}
1002-
}
1003-
}
1004-
1005-
if (this.bpClient) {
1006-
this.driver.controlFlow().execute(() => {
1007-
return this.bpClient.setSynchronization(!this.internalIgnoreSynchronization);
1008-
});
1009-
}
1010-
1011-
this.driver.controlFlow().execute(() => {
1012-
return this.plugins_.onPageStable().then(() => {
1013-
deferred.fulfill();
1014-
}, deferred.reject);
1015-
});
977+
throw new Error('Error while running testForAngular: ' + err.message);
978+
});
1016979

1017-
return deferred.promise;
980+
})
981+
.then((angularVersion) => {
982+
// Load Angular Mocks
983+
if (angularVersion === 1) {
984+
// At this point, Angular will pause for us until angular.resumeBootstrap is called.
985+
let moduleNames: string[] = [];
986+
let modulePromise: wdpromise.Promise<void> = wdpromise.when(null);
987+
for (const {name, script, args} of this.mockModules_) {
988+
moduleNames.push(name);
989+
let executeScriptArgs = [script, msg('add mock module ' + name), ...args];
990+
modulePromise = modulePromise.then(
991+
() => this.executeScriptWithDescription.apply(this, executeScriptArgs)
992+
.then(null, (err: Error) => {
993+
throw new Error(
994+
'Error while running module script ' + name + ': ' + err.message);
995+
}));
996+
}
997+
998+
return modulePromise.then(
999+
() => this.executeScriptWithDescription(
1000+
'window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = ' +
1001+
'angular.resumeBootstrap(arguments[0]);',
1002+
msg('resume bootstrap'), moduleNames));
1003+
} else {
1004+
// TODO: support mock modules in Angular2. For now, error if someone
1005+
// has tried to use one.
1006+
if (this.mockModules_.length > 1) {
1007+
throw 'Trying to load mock modules on an Angular2 app is not yet supported.';
1008+
}
1009+
}
1010+
})
1011+
.then(() => {
1012+
// Reset bpClient sync
1013+
if (this.bpClient) {
1014+
return this.driver.controlFlow().execute(() => {
1015+
return this.bpClient.setSynchronization(!this.internalIgnoreSynchronization);
1016+
});
1017+
}
1018+
})
1019+
.then(() => {
1020+
// Run Plugins
1021+
return this.driver.controlFlow().execute(() => {
1022+
return this.plugins_.onPageStable();
1023+
});
1024+
})
1025+
.then(() => null);
10181026
}
10191027

10201028
/**

0 commit comments

Comments
 (0)