Git Product home page Git Product logo

webdriver-async-runner's Introduction

@rickyli79/webdriver-async-runner

Solution for webdriver safty executeAsyncScript, handling errors.

unknown exception is executeAsyncScript

Scenario

Here one script to be execute by Selenium Webdriver.
And the script may occurs error for some reason.

// a js script that may cause error in runtime
const args = arguments;
function main(text) {
  if ( typeof text!=='string' ) {
    throw new Error('text MUST BE a string');
  }
  return text;
}
const result = main(args[0]);
const callback = args[args.length-1];
callback(result);

Selenium Webdriver side

// JAVA
String jsScriptContent = loadFromScriptFile("jsScript.async.js");
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);

JavascriptExecutor js = (JavascriptExecutor)driver;
Object result = js.executeAsyncScript(jsScriptContent, 1); // `1` is not a string

When error occurs, JAVA side would not get the execption immediately. Until the script timeout.

Solution

wrap the code like this. The wrapper will handle any error in runtime

const asyncRun = require('@rickyli79/webdriver-async-runner');

const args = arguments;
function main(text) {
  if ( typeof text!=='string' ) {
    throw new Error('text MUST BE a string');
  }
  return text;
}
asyncRun(
  ()=> { return main(args[0]) } ,   // can be Promise or not
  args,   // will extract the last member as callback
  false,  // do not JSON.stringify the result to callback;
);

And Selenium Webdriver side SHOULD detect the error like

// JAVA
String jsScriptContent = loadFromScriptFile("jsScript.async.js");
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);

JavascriptExecutor js = (JavascriptExecutor)driver;
Object result = js.executeAsyncScript(jsScriptContent, 1);
if ( result.getClass() == String.class ) {
  if ( result.startsWith("{\"__error__\":") ) {
    // throw out Exception here
  }
}

large callback result

When webdriver run by Selenium Grid, large callback result ( string type and over 2048KB ), callback will fail to response to script machine

Scenario

Here one script to be execute by Selenium Webdriver.
And the script may occurs error for some reason.

// returns large string , over 2048KB
const args = arguments;
function main(text) {
  return text+text+text+text+text+text+text+text+text+text; // 10 times
}
const result = main(args[0]);
const callback = args[args.length-1];
callback(result);

Selenium Webdriver side

// JAVA
String jsScriptContent = loadFromScriptFile("jsScript.async.js");
String largeText = loadStringContent(); // for example, 300KB

driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
JavascriptExecutor js = (JavascriptExecutor)driver;
Object result = js.executeAsyncScript(jsScriptContent, largeText); // will never recieve, and script timeout

Solution

const asyncRun = require('@rickyli79/webdriver-async-runner');

const args = arguments;
function main(text) {
  return text+text+text+text+text+text+text+text+text+text; // 10 times
}
asyncRun(()=> { return main(args[0]) },args,false);
export type Chunk = {
  __result__: number,
  content: string,

  chunkSize: number,
  current: number,
  total: number;
};
// JAVA
String jsScriptContent = loadFromScriptFile("jsScript.async.js");
String largeText = loadStringContent(); // for example, 300KB

driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
JavascriptExecutor js = (JavascriptExecutor)driver;
Object result = js.executeAsyncScript(jsScriptContent, largeText);
if ( result.getClass() == String.class ) {
  if ( result.startsWith("{\"__error__\":") ) {
    // throw out Exception here
  } else if ( result.startsWith("{\"__result__\":") ) {
    JSONObject chunk = JSONObject.parse(result);
    String resultId = (String)chunk.get("__result__");
    int total = (int)chunk.get("total");
    String resultTotal = (String)chunk.get("content");
    String getRunResultScript = loadFromScriptFile("getRunResult.sync.js");
    for( int idx=2; idx<=total; idx++ ) {
      String iChunkStr = (String)js.executeSyncScript(getRunResultScript, resultId, idx);
      JSONObject iChunk = JSONObject.parse(iChunkStr);
      resultTotal += (String)iChunk.get("content");
    }
    result = resultTotal; // here the `result` finally is the over 3MB
  }
}
result

webdriver-async-runner's People

Contributors

rickyli79 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.