npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

automatonic

v0.1.1

Published

Browser automation as an electron library

Downloads

13

Readme

Automatonic

automatonic is a library that, for now, is meant to be used within an Electron app for browser automation. Electron provides pretty good APIs for doing automation, but they're not particularly convenient for things like automated testing. There are things like Nightmare.js the provide an abstraction on top of Electron, and this is largely inspired by those.

Why not just use Nightmare.js?

Reasons. Here are a few:

  • The page I was trying to test would cause Nightmare.js to freeze, but the same test when run manually in Electron or PhantomJS worked fine.
  • You can't use Nightmare.js from within an Electron app.
  • You can't test multi-session interaction (multiple browsers, like chat) because you only get access to one BrowserWindow.

API

All of the API methods return a Promise, and all of them use an internal queue to make sure actions run in the correct order. As this is still in a proof-of-concept phase, the API is fairly limited. At some point, there may be an API to use directly from node that spins up a child process with Electron and proxies back and forth like Nightmare.js.

Browser

  • constructor([options object]) or Browser.new([options object])

    The options object is passed straight through to Electron's BrowserWindow. If not specified, webPreferences.nodeIntegration is set to false because it can interfere with module loaders and has the tiny risk of having a third party script completely own your machine.

    The automatonic specific options are:

    • pollInterval: number of milliseconds between element checks when waiting for an element to appear. Default is 200.
    • typingInterval: number of milliseconds between characters when typing into an input. Default is 50.
    • exposeElectronAs: string variable name to expose the electron module to the page e.g. window.${exposeElectronAs} = require('electron'). This is implemented with a preload script, so it works even if nodeIntegration is disabled (the default).
    • preloadScript: string of extra script that gets added to any generated preload script to be handed to electron.

    Any generated preload scripts are created as temporary files that are cleaned up when the main process exits.

Properties

  • browser

    The BrowserWindow instance belonging to this Browser.

Methods

  • goto(url[, options object])

    Navigate to the given url. Any options are passed directly to BrowserWindow.loadURL, and the returned Promise resolves when the page load is complete.

  • execute(function[, ...args])

    Execute the given function in the browser by toString()ing it, JSON.stringifying the arguments, shipping them to the render instance, wrapping everything up in a Promise, and returning the result.

  • click(selector[, options object])

    Find an element with the given selector and trigger mouseover, mousedown, click, and mouseup events. This will wait up to 1s (default, change with the timeout option) for the element to appear.

  • type(selector, string[, options object])

    Find an element with the given selector, focus it, and then pass each character from the string into the target element. Each character will trigger keydown, keypress, update the value, input, and keyup. Once all of the characters are added, a change event will be triggered. This will wait up to 1s (default, change with the timeout option) for the element to appear. Specifying append: true will not empty the target input before sending characters.

  • waitFor(selector, timeout = 5000)

    Wait up to timeout milliseconds for an element matching selector to appear on the page.

  • waitFor(timeout = 1000)

    Wait for timeout milliseconds before continuing.

  • checkFor(selector)

    Immediately check to see if an element matching selector exists.

  • checkForText(string)

    Immediately check to see if string exists in the page HTML. If string is a RegExp, then its test method will be used to determine whether or not there is a match.

  • checkpoint()

    Sets a checkpoint in the queue. If any step before the checkpoint fails, everything between the checkpoint and the failure will be removed from the queue. The Promise returned will resolve when all of the steps before the checkpoint have resolved.

  • close()

    Closes and disposes of the Browser.

Utility methods

  • run(generator)

    This is basically a copy of co that only allows yielding Promises. This is particularly useful for allowing easy branching within an automation. This returns a Promise that resolves when the generator has nothing left to yield.

  • sleep(milliseconds)

    Returns a Promise that resolves after millisecondsms have elapsed.

Usage

const { Browser, run, sleep } = require('automatonic');
run(function*() {
  const I = new Browser();
  I.goto('https://google.com');

  // let's give 'em a second to settle
  yield sleep(1000);

  // do a search
  I.type('#lst-ib', 'automatonic\n');
  I.click('button[name=btnG]');

  // wait for a result and grab its title
  I.wait('h3.r a');
  const first = yield I.execute(function() {
    return document.querySelector('h3.r a').innerText;
  });

  if (~first.toLowerCase().indexOf('wikipedia')) {
    console.log("hey look, it's a Wikipedia link");
  } else {
    console.log("it's not a Wikipedia link, let's click it");
    I.click('h3.r a');
  }

  yield sleep(20000);
  I.close();
}).then(null, err => {
  console.error('OH NOES!', err);
});