Angular-Protractor synchronization for non-angular apps (React, Vue, ...)
Using this library you can get rid of almost all browser.sleeps
and browser.waits
in your protractor tests and relly on the same synchronization mechanism that is used by protract and angular.
- Install synctractor
npm i --save synctractor
- Remove
ignoreSynchronization
from protractor config as it is not needed anymore - Add this as the very first lines of your app entry point:
(see
import * as synctractor from 'synctractor'; synctractor.init(); synctractor.monitorFetch(); synctractor.monitorTimeout((_, t) => t !== 11000);
setTimeout
details bellow for explanation of this magic number)
There is automatic mode (synctractor.monitorXXX()
) where you setup synctractor on your app entry point and that is all and there is also a manual mode, where you only initialize synctractor but you have to update calls all over your code. In automatic mode. you can get to unmonitored calls by synctractor.nativeXXX()
- Initialize synctractor
import * as synctractor from 'synctractor'; synctractor.init();
- Replace calls in your code:
fetch
=>synctractor.fetch
setTimeout
=>synctractor.setTimeout
clearTimeout
=>synctractor.clearTimeout
- Manual -
synctractor.fetch(...)
- Automatic -
synctractor.monitorFetch()
- Manual -
synctractor.setTimeout()
andsynctractor.clearTimeout()
- Automatic -
synctractor.monitorTimeout()
- There is one glitch with
monitorTimeout()
. Protractor itself usessetTimeout
. This call will be captured by synctractor and protractor (as it is waiting for its own wait :) ) will eventually fail. To workaround this you can add a fitler function to amonitorTimeout
. Calls tosetTimeout
where this function returnsfalse
will not be monitored. By default protractor sets timeout to11000
. You can use this value to fitler out calls made by protractor.This value can be changed in protractor config by settingsynctractor.monitorTimeout((_, t) => t !== 11000);
allScriptsTimeout
value.
- There is one glitch with
- In some cases you might want to group multiple backend calls into single protractor wait. In that case you can use
trackBackgroundOp
function.await trackBackgroundOp(async () => { await call1(); doSomeMagic(); await call2(); });
- AJAX
- setInterval
See examples
folder. There is very simple example with a setTimeout
written in couple frameworks and one protractor test.
- Clone this repository
- Build synctractor (
npm run build
in a root folder) - Pick a framework and enter (...and keep it running):
npm i
npm start
- In a
protractor
folder run:
npm i
npm run test
Protractor tests should click on a button and wait for counter to increment.
Synctractor (fetch monitoring only) is succesfully used on a medium sized react+mobx app for last few months. SetTimeout was written only because of the examples and was not tested in a production yet.