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

Commit 4e40fb1

Browse files
committed
feat(browser): chain promises in browser.get (#4017)
Closes #3904
1 parent 33393ca commit 4e40fb1

File tree

1 file changed

+125
-119
lines changed

1 file changed

+125
-119
lines changed

Diff for: lib/browser.ts

+125-119
Original file line numberDiff line numberDiff line change
@@ -928,131 +928,137 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
928928
get(destination: string, timeout = this.getPageTimeout) {
929929
destination = this.baseUrl.indexOf('file://') === 0 ? this.baseUrl + destination :
930930
url.resolve(this.baseUrl, destination);
931-
let msg = (str: string) => {
932-
return 'Protractor.get(' + destination + ') - ' + str;
933-
};
934-
935-
if (this.bpClient) {
936-
this.driver.controlFlow().execute(() => {
937-
return this.bpClient.setWaitEnabled(false);
938-
});
939-
}
940-
941931
if (this.ignoreSynchronization) {
942-
this.driver.get(destination);
943-
return this.driver.controlFlow().execute(() => this.plugins_.onPageLoad()).then(() => {});
932+
return this.driver.get(destination)
933+
.then(() => this.driver.controlFlow().execute(() => this.plugins_.onPageLoad()))
934+
.then(() => null);
944935
}
945936

946-
let deferred = wdpromise.defer<void>();
947-
948-
this.driver.get(this.resetUrl).then(null, deferred.reject);
949-
this.executeScriptWithDescription(
950-
'window.name = "' + DEFER_LABEL + '" + window.name;' +
951-
'window.location.replace("' + destination + '");',
952-
msg('reset url'))
953-
.then(null, deferred.reject);
954-
955-
// We need to make sure the new url has loaded before
956-
// we try to execute any asynchronous scripts.
957-
this.driver
958-
.wait(
959-
() => {
960-
return this
961-
.executeScriptWithDescription('return window.location.href;', msg('get url'))
962-
.then(
963-
(url: any) => {
964-
return url !== this.resetUrl;
965-
},
966-
(err: IError) => {
967-
if (err.code == 13) {
968-
// Ignore the error, and continue trying. This is
969-
// because IE driver sometimes (~1%) will throw an
970-
// unknown error from this execution. See
971-
// https://github.com/angular/protractor/issues/841
972-
// This shouldn't mask errors because it will fail
973-
// with the timeout anyway.
974-
return false;
975-
} else {
976-
throw err;
977-
}
978-
});
979-
},
980-
timeout, 'waiting for page to load for ' + timeout + 'ms')
981-
.then(null, deferred.reject);
982-
983-
this.driver.controlFlow().execute(() => {
984-
return this.plugins_.onPageLoad();
985-
});
937+
let msg = (str: string) => {
938+
return 'Protractor.get(' + destination + ') - ' + str;
939+
};
986940

987-
// Make sure the page is an Angular page.
988-
this.executeAsyncScript_(
989-
clientSideScripts.testForAngular, msg('test for angular'), Math.floor(timeout / 1000),
990-
this.ng12Hybrid)
991-
.then(
992-
(angularTestResult: {ver: number, message: string}) => {
993-
let angularVersion = angularTestResult.ver;
994-
if (!angularVersion) {
995-
let message = angularTestResult.message;
996-
logger.error(`Could not find Angular on page ${destination} : ${message}`);
997-
throw new Error(
998-
`Angular could not be found on the page ${destination}. If this is not an ` +
999-
`Angular application, you may need to turn off waiting for Angular. Please ` +
1000-
`see https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load`);
1001-
}
1002-
return angularVersion;
1003-
},
1004-
(err: Error) => {
1005-
throw new Error('Error while running testForAngular: ' + err.message);
1006-
})
1007-
.then(loadMocks, deferred.reject);
1008-
1009-
let self = this;
1010-
function loadMocks(angularVersion: number) {
1011-
if (angularVersion === 1) {
1012-
// At this point, Angular will pause for us until angular.resumeBootstrap is called.
1013-
let moduleNames: string[] = [];
1014-
for (const {name, script, args} of self.mockModules_) {
1015-
moduleNames.push(name);
1016-
let executeScriptArgs = [script, msg('add mock module ' + name), ...args];
1017-
self.executeScriptWithDescription.apply(self, executeScriptArgs)
941+
return this.driver.controlFlow()
942+
.execute(() => {
943+
return wdpromise.when(null);
944+
})
945+
.then(() => {
946+
if (this.bpClient) {
947+
return this.driver.controlFlow().execute(() => {
948+
return this.bpClient.setWaitEnabled(false);
949+
});
950+
}
951+
})
952+
.then(() => {
953+
// Go to reset url
954+
return this.driver.get(this.resetUrl);
955+
})
956+
.then(() => {
957+
// Set defer label and navigate
958+
return this.executeScriptWithDescription(
959+
'window.name = "' + DEFER_LABEL + '" + window.name;' +
960+
'window.location.replace("' + destination + '");',
961+
msg('reset url'));
962+
})
963+
.then(() => {
964+
// We need to make sure the new url has loaded before
965+
// we try to execute any asynchronous scripts.
966+
return this.driver.wait(() => {
967+
return this.executeScriptWithDescription('return window.location.href;', msg('get url'))
968+
.then(
969+
(url: any) => {
970+
return url !== this.resetUrl;
971+
},
972+
(err: IError) => {
973+
if (err.code == 13) {
974+
// Ignore the error, and continue trying. This is
975+
// because IE driver sometimes (~1%) will throw an
976+
// unknown error from this execution. See
977+
// https://github.com/angular/protractor/issues/841
978+
// This shouldn't mask errors because it will fail
979+
// with the timeout anyway.
980+
return false;
981+
} else {
982+
throw err;
983+
}
984+
});
985+
}, timeout, 'waiting for page to load for ' + timeout + 'ms');
986+
})
987+
.then(() => {
988+
// Run Plugins
989+
return this.driver.controlFlow().execute(() => {
990+
return this.plugins_.onPageLoad();
991+
});
992+
})
993+
.then(() => {
994+
// Make sure the page is an Angular page.
995+
return this
996+
.executeAsyncScript_(
997+
clientSideScripts.testForAngular, msg('test for angular'),
998+
Math.floor(timeout / 1000), this.ng12Hybrid)
1018999
.then(
1019-
null,
1000+
(angularTestResult: {ver: number, message: string}) => {
1001+
let angularVersion = angularTestResult.ver;
1002+
if (!angularVersion) {
1003+
let message = angularTestResult.message;
1004+
logger.error(`Could not find Angular on page ${destination} : ${message}`);
1005+
throw new Error(
1006+
'Angular could not be found on the page ${destination}.' +
1007+
`If this is not an Angular application, you may need to turn off waiting for Angular.
1008+
Please see
1009+
https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load`);
1010+
}
1011+
return angularVersion;
1012+
},
10201013
(err: Error) => {
1021-
throw new Error(
1022-
'Error while running module script ' + name + ': ' + err.message);
1023-
})
1024-
.then(null, deferred.reject);
1025-
}
1026-
1027-
self.executeScriptWithDescription(
1028-
'window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = ' +
1029-
'angular.resumeBootstrap(arguments[0]);',
1030-
msg('resume bootstrap'), moduleNames)
1031-
.then(null, deferred.reject);
1032-
} else {
1033-
// TODO: support mock modules in Angular2. For now, error if someone
1034-
// has tried to use one.
1035-
if (self.mockModules_.length > 1) {
1036-
deferred.reject(
1037-
'Trying to load mock modules on an Angular2 app ' +
1038-
'is not yet supported.');
1039-
}
1040-
}
1041-
}
1042-
1043-
if (this.bpClient) {
1044-
this.driver.controlFlow().execute(() => {
1045-
return this.bpClient.setWaitEnabled(!this.internalIgnoreSynchronization);
1046-
});
1047-
}
1048-
1049-
this.driver.controlFlow().execute(() => {
1050-
return this.plugins_.onPageStable().then(() => {
1051-
deferred.fulfill();
1052-
}, deferred.reject);
1053-
});
1054-
1055-
return deferred.promise;
1014+
throw new Error('Error while running testForAngular: ' + err.message);
1015+
});
1016+
})
1017+
.then((angularVersion) => {
1018+
// Load Angular Mocks
1019+
if (angularVersion === 1) {
1020+
// At this point, Angular will pause for us until angular.resumeBootstrap is called.
1021+
let moduleNames: string[] = [];
1022+
let modulePromise: wdpromise.Promise<void> = wdpromise.when(null);
1023+
for (const {name, script, args} of this.mockModules_) {
1024+
moduleNames.push(name);
1025+
let executeScriptArgs = [script, msg('add mock module ' + name), ...args];
1026+
modulePromise = modulePromise.then(
1027+
() => this.executeScriptWithDescription.apply(this, executeScriptArgs)
1028+
.then(null, (err: Error) => {
1029+
throw new Error(
1030+
'Error while running module script ' + name + ': ' + err.message);
1031+
}));
1032+
}
1033+
1034+
return modulePromise.then(
1035+
() => this.executeScriptWithDescription(
1036+
'window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = ' +
1037+
'angular.resumeBootstrap(arguments[0]);',
1038+
msg('resume bootstrap'), moduleNames));
1039+
} else {
1040+
// TODO: support mock modules in Angular2. For now, error if someone
1041+
// has tried to use one.
1042+
if (this.mockModules_.length > 1) {
1043+
throw 'Trying to load mock modules on an Angular2 app is not yet supported.';
1044+
}
1045+
}
1046+
})
1047+
.then(() => {
1048+
// Reset bpClient sync
1049+
if (this.bpClient) {
1050+
return this.driver.controlFlow().execute(() => {
1051+
return this.bpClient.setWaitEnabled(!this.internalIgnoreSynchronization);
1052+
});
1053+
}
1054+
})
1055+
.then(() => {
1056+
// Run Plugins
1057+
return this.driver.controlFlow().execute(() => {
1058+
return this.plugins_.onPageStable();
1059+
});
1060+
})
1061+
.then(() => null);
10561062
}
10571063

10581064
/**

0 commit comments

Comments
 (0)