You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 29, 2024. It is now read-only.
Preface: This idea got uglier while researching the implementation details. I think #3858 is probably a better idea, but I'm making this issue anyway just to write everything down
We could replace browser.ignoreSynchronization with browser.synchronizationMode which would be either 'ALWAYS', 'NEVER', or 'DETECT' (I'm open to suggestions for different names). ALWAYS would be equivalent to browser.ignoreSynchronization = true, NEVER would be equivalent to browser.ignoreSynchronization = false, and DETECT would work as follows:
First, we replace testForAngular with the following logic:
functiontestForAngular(callback: (data: {ver?: number})=>void){// Pretend we add `undefined` checks throughout this functionfunctiontestForAngular_inner(callback: (data: {ver?: number})=>void){if(looksLikeNg1Obj(window.angular)||systemJsHas('angular')){callback({ver: 1});}elseif(looksLikeModernNgObj(window.ng||window.angular)||hasTestabilityFunctions(window)||systemJsHas('@angular')){callback({ver: 2});}else{waitForSystemJS(callback);}}functionsystemJsHas(packageName: string): boolean{letsysJs=window.SystemJS||window.System;// Pretend this for loop syntax worksfor(letnamein(sysJs.mapor_.invert(sysJs.map)orsysJs.definedorsysJs._loader.modulesorsysJs._loader.importPromises)){if((newRegExp('(\/|^)'+packageName+'(\/|$)').test(packageName)){returntrue;}}returnfalse;}varimportDone: {[url: string]: boolean}={};functionwaitForSystemJS(callback: (data: {ver?: number})=>void){letsysJs=window.SystemJS||window.System;letwaitForImport=(promise: Promise<any>,url: string)=>{importDone[url]=false;letonComplete=()=>{importDone[url]=true;// If all promises are resolved, call testForAngular_inner() againfor(letresolvedofimportResolved){if(!resolved){return;}}testForAngular_inner(callback);};promise.then(onComplete,onComplete);}letnewPromises=false;for(leturlinsysJs._loader.importPromises){if(sysJs._loader.importPromises[url]&&(importDone[url]===undefined)){importResolved[url]=false;waitForImport(sysJs._loader.importPromises[url],url);}}if(!newPromises){callback({});// Give up, no angular}}testForAngular_inner(callback);}
(back when I came up with this idea, I didn't realize what an issue SystemJS was going to be)
Now, in browser.get, we use testForAngular, and based on the result of that we decide if we want to do synchronization. Some pitfalls:
SystemJS.defined and SystemJS._loader are not public APIs
No support for other package managers
Eventually there will be native package managers, but maybe they'll block js execution like <script> tags do, or maybe there will be something analogous to DOMContentLoaded for them.
This could still fail if someone is accessing angular indirectly through another package which has angular hard-coded
In the examples I've seen, zone.js always seems to be loaded directly via a <script> tag. If we see window.Zone, we could wait a few seconds for angular to show up.
We could make a package like @protractor/testability-flag and ask users to include it client side in a <script> tag.
The text was updated successfully, but these errors were encountered:
Preface: This idea got uglier while researching the implementation details. I think #3858 is probably a better idea, but I'm making this issue anyway just to write everything down
We could replace
browser.ignoreSynchronization
withbrowser.synchronizationMode
which would be either'ALWAYS'
,'NEVER'
, or'DETECT'
(I'm open to suggestions for different names).ALWAYS
would be equivalent tobrowser.ignoreSynchronization = true
,NEVER
would be equivalent tobrowser.ignoreSynchronization = false
, andDETECT
would work as follows:First, we replace
testForAngular
with the following logic:(back when I came up with this idea, I didn't realize what an issue
SystemJS
was going to be)Now, in
browser.get
, we usetestForAngular
, and based on the result of that we decide if we want to do synchronization. Some pitfalls:browser.get
(e.g. someone clicks on a link), we wouldn't bootstrap and end up using an outdated synchronization setting from a previous page. However, Bootstrapping should (mostly) work with Browser-initiated navigation (e.g. clicking on links) #3857 should address that.SystemJS.defined
andSystemJS._loader
are not public APIs<script>
tags do, or maybe there will be something analogous toDOMContentLoaded
for them.Alternative ideas
<script>
tag. If we seewindow.Zone
, we could wait a few seconds for angular to show up.@protractor/testability-flag
and ask users to include it client side in a<script>
tag.The text was updated successfully, but these errors were encountered: