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

Feature Request: Allow users to use a custom ControlFlow/scheduler #4024

Open
sjelin opened this issue Jan 27, 2017 · 0 comments
Open

Feature Request: Allow users to use a custom ControlFlow/scheduler #4024

sjelin opened this issue Jan 27, 2017 · 0 comments

Comments

@sjelin
Copy link
Contributor

sjelin commented Jan 27, 2017

We talked briefly about implementing our own alternative to the WebDriver Control Flow, since it is going away but many of our users (presumably) find it useful. Based on my work on zoned-scheduler (more on that below), it's unlikely that we'll be able to make a perfect alternative scheduler that all our users will love.

However, we could allow users to provide a custom scheduler implementation if they so desired, much like jasminewd now does. This would allow users to port a version of WebDriver's Control Flow, or use zoned-scheduler, or whatever they wished.


zoned-scheduler

I implemented zoned-scheduler, which uses zone.js to achieve almost all the functionality of WebDriver's Control Flow without adding nearly as much complexity. In particular:

  • zoned-scheduler doesn't require any specific promise implementation. This means users (and Protractor devs) won't run into nearly as many problems when using 3rd party libraries or async/await.
  • zoned-scheduler has a simple 2D array for its task queue, and a codebase of just 202 lines (not counting tests and other support files). This reduced complexity should be easier to debug.

The one thing which WebDriver's Control Flow can do which zoned-scheduler can't is follow then blocks:

// With WebDriver's Control Flow

var wd_taskA = browser.driver.controlFlow.execute(() => {
  console.log('wd - first');
});
wd_taskA.then(() => {
  // The WebDriver Control Flow knows this is a continuation of Task A
  return WebDriverPromiseWhichResolvesIn1000ms.then(() => {
    console.log('wd - second');
  });
});
var wd_taskB = browser.driver.controlFlow.execute(() => {
  // Task B is delayed until after `WebDriverPromiseWhichResolvesIn1000ms` resolves
  console.log('wd - third');
});

// With zoned-scheduler

var zs_taskA = zonedScheduler.schedule(() => {
  console.log('zs - first');
});
zs_taskA.then(() => {
  // zoned-scheduler can't tell that this is a continuation of Task A,
  // as it lacks a custom promise implementation
  return PromiseWhichResolvesIn1000ms.then(() => {
    console.log('zs - third');
  });
});
var zs_taskB = zonedScheduler.schedule(() => {
  // Task B is not delayed by `PromiseWhichResolvesIn1000ms`
  console.log('zs - second');
});

This is a minor problem (since you really should have scheduled the middle block as a separate task), but it would sill be a breaking change for some users. I suspect (though I haven't mathematically proven it) that it's impossible to write a scheduler which can follow then blocks without using some kind of custom promise implementation (e.g. WebDriver's ManagedPromise).

zoned-scheduler also still has the problem where it is difficult to set break points properly (described here: SeleniumHQ/selenium#2969). As such, we're unlikely to put it (or anything similar) officially into Protractor. Still, I think it could be useful to many of our users, and I think an option for a custom scheduler would be nice.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant