Giter Club home page Giter Club logo

corylr / user-routine Goto Github PK

View Code? Open in Web Editor NEW
9.0 3.0 1.0 4.22 MB

User-Routine is a JavaScript library to automate user routines on web pages. You can easily test features or create tutorials with actions such as click, await, and fill.

Home Page: https://corylr.github.io/user-routine/

License: MIT License

TypeScript 60.39% HTML 28.18% JavaScript 11.43%
javascript spa application automated click e2e end-to-end single-page test typescript

user-routine's Introduction

User-Routine

User-Routine is a JavaScript library to automate user routines on web pages. You can easily test features or create tutorials with actions such as click, await, and fill.

✨ See the Live Demo

Example:

userRoutine([
  'fill form>input.name Cory',
  'click button.submit',
  'await div.result',
  'exists div With this text',
]);

Table of Contents

Access

Options:

1. Install from NPM (npm install user-routine) and import

import { userRoutine } from 'user-routine';
// OR
const { userRoutine } = require('user-routine');

2. Or include the User-Routine script file (user-routine.blob.js) in your HTML:

<!-- Declares function `userRoutine` (CDN) -->
<script src="https://cdn.jsdelivr.net/gh/CoryLR/user-routine/dist/user-routine.blob.js"></script>
<!-- OR -->
<!-- Declares function `userRoutine` (local file) -->
<script src="./user-routine.blob.js"></script>

3. Or copy the portable template from here: user-routine.template.js

  • ^ This works with zero setup if you copy-paste the contents into a browser console or into client-side JavaScript

Usage

User-Routine is served as a function named userRoutine.

Simple Examples

Run a test:

userRoutine([
  'click button.btn', // Target using CSS selectors
  'await div.result Result Text', // Await result text
], { message: 'Testing the button' });

Display a tutorial:

userRoutine([
  'comment .some-form First, fill this out',
  'comment .submit-button Then, hit Submit!',
], { message: 'Tutorial', tutorialMode: true });

Customize options to run quickly and quietly:

userRoutine([
  'fill form>input Mock input text',
  'click button.submit',
  'await div.some-expected-result',
  // etc...
], {
  message: 'Testing the button',
  displayProgress: false, // default is true
  logProgress: false, // default is true
  globalDelay: 50, // default is 500 (0.5 seconds)
  awaitTimeout: 1500, // default is 15000 (15 seconds)
});

Input Parameter Details

function userRoutine(actions: string[] OR string, options: UserRoutineOptions?)

  • 1: Actions List (String (separate actions by new lines) or Array of strings/functions, required)
    • Action strings & examples:
      • append
        • Add text to the end of an element's textContent
        • 'append section>p Appended text'
      • await
        • Await for something to appear
        • 'await .modal.success-message' or 'await h1 With This Text'
      • !await
        • Await for something to disappear
        • '!await .spinner' or '!await h1 This title should disappear'
      • click
        • Click on something
        • 'click button.submit' or 'click button With This Text'
      • comment
        • Show a tooltip to point something out
        • 'comment input.name Type your name here'
      • exists
        • Check to see if something exists in any css selector matches
        • 'exists .class-name' or 'exists h1 With This Text'
      • !exists
        • Check to see if something doesn't exist in any css selector matches
        • '!exists h1 Incorrect text'
      • fill
        • Fill the value attribute of a specific element
        • 'fill form>input.name Cory Rahman'
      • log
        • Record a message
        • 'log Some message'
      • nav
        • Use hash navigation
        • 'nav #id' or 'nav #/some/hash/routing/path'
      • value
        • Check the value attribute of a specific element
        • 'value input.required' or 'value input.name Test User 1'
      • wait
        • Wait for some time
        • 'wait 3000' (3 seconds)
      • write
        • Overwrite textContent of an element
        • 'write p Overwritten text'
    • Selector:
      • CSS selector like button.class-name
      • The CSS selector should not contain spaces by default. Either use >> instead of spaces like await .container>>div Result Text) or pass a custom action string separator in the Options
    • Data:
      • Required argument for append, comment, fill, log, value, wait, and write
      • Optional argument for await, click, exists, and value
  • 2: Options (Object, optional)
    • awaitTimeout: (default: 15000) How long in milliseconds to wait for an element using the await command
    • continueOnFailure: (default: false) Continue to run actions even if one fails
    • displayMessage: (default: true) Show message at the top of the page
    • displayProgress: (default: true) Show animations of actions visually on the page using tooltips
    • displaySpeed: (default: 1) Animation speed for displayProgress tooltips (0.5 = half speed, 2 = double speed, etc)
    • globalDelay: (default: 500) Time between actions in milliseconds
    • keyboardControls: (default: true) Enables play/pause/stop with space and escape keys
    • logCollapse: (default: false) Initializes the console group collapsed
    • logProgress: (default: true) Show real-time progress in the browser console
    • logResult: (default: true) Show the final result in the browser console
    • message: (default: 'User-Routine') Label to show in the console and in the DOM
    • messageAttribution: (default: 'User-Routine') Subtitle text shown when custom message is provided
    • overrideCss: (default: '') Override default User-Routine CSS, target classes such as .user-routine-message, .user-routine-focus-box, or .user-routine-tooltip
    • separator: (default: ' ' (space)) Choose different text to separate the different parts of the action string. For example, with separator set to '; ', you could write an action string like 'await; .container div[name="Result Box"]; Result Text'.
    • simultaneousAllowed: (default: false) Allow the User-Routine to run even if one is already running
    • tutorialMode: (default: false) Add a "Next" button to tooltips, and only show tooltips for "log" and "comment" actions

Output Details

  • The userRoutine function returns a Promise resolving to type UserRoutineReturn:
    • export type UserRoutineReturn = { success: boolean, log: string[], message: string, configuration: UserRoutineOptions };
  • Updates are also logged to the browser console like so:
[User-Routine] Message
  * Filled the value of form>input.name to 'Cory'
  * Clicked on button[type="submit"]
  * Awaiting 'div.success-message'...
  * ...Found 'div.success-message'
  * Done, success: true
  Result: { success: true, log: Array(4), message: 'Message' }

More Resources

Examples

Live Demo

✨ See the Live Demo

Template

See the user-routine.template.js for examples of running multiple sequential tests using async/await. This template also works with zero setup if you copy-paste the contents into a browser console or into client-side JavaScript

Use-cases

Fill inputs with fill and interact with click using Selectors:

userRoutine([
  'fill input[type="text"] Hello, world!', // Fills in the input
  'fill input[type="number"] 20',
  'click button.some-class', // Clicks a button with class 'some-class'
  'click div With certain text', // Clicks on the given text within a div
  'click * With certain text', // Clicks on the given text regardless of containing element
  'click body>>.nested-div', // Use `>>` instead of spaces in CSS selectors
]);
  • Note: To use spaces in CSS selectors, either replace the spaces with >> (like body>>.class instead of body .class) or define a custom separator using the separator option (like separator: '; ').

Validate the DOM with exists and value:

userRoutine([
  'exists p.some-class', // Checks for the existence of this element
  'exists p.some-class With certain text', // Also checks if it includes certain text
  '!exists p.some-class', // Validates that the element does not exist
  '!exists p.some-class With certain text', // Validates that the element does not exist with certain text
  'value input.required', // Validates that the element has any value
  'value input.name Jane Doe', // Validates that the element has a value of "Jane Doe"
]);

Deal with timing using await and wait:

userRoutine([
  'await div.some-popup', // Awaits the existence of this element
  'await div.some-popup With certain text', // Awaits for it to include certain text
  '!await div.some-spinner', // Awaits the non-existence of this element
  '!await div.some-popup With certain text', // Awaits for it to not include certain text
  'wait 3000', // waits 3 seconds
]);
  • Note: The default await timeout is 15000 ms (15 seconds), overwrite using the awaitTimeout option.

Navigate within a single-page application using nav:

userRoutine([
  'nav #some-id',
  'nav #/some/hash/routing/path',
  'nav #', // Back to the top
]);

Add notes with append, log, and write:

userRoutine([
  'write h1 Testing successful!', // overwrites the h1's textContent
  'append h1  - Testing successful!', // appends to the h1's textContent
  'log The testing is complete.',
]);

Pass options as a second argument:

userRoutine([
  'fill input.name Cory',
  'click button[type="submit"]',
], { globalDelay: 1000 });
// ^ Options object with 1 second between actions
  • Note: See Usage for a list of options

Development

Maintainers

Getting Started

Continuous Development

To publish:

  1. Bump the version number in the package.json
  2. npm i
  3. npm run build
  4. Test one last time
  5. Fix any issues then commit changes
  6. npm publish --access public

TO DO:

  • Add a tutorial walk-through to the demo page, using User-Routine to showcase User-Routine
  • Improve tutorialMode by automating progress via await and other actions instead of relying on the Next button
  • Separate actions into externally-callable functions
  • Add global case-sensitivity option
  • (Maybe) Add count action to count instances of a particular CSS selector
  • (Maybe) Add copy/paste actions
  • (Maybe) Add ability to keybind User-Routine(s) to keys
  • (Maybe) Add copy/paste actions

user-routine's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

stargator

user-routine's Issues

Add "wait" feature

Add an option to wait for a specific element to appear:

Action string example: 'wait .popup'

Full example:

  spaCheck([
    'click button',
    'wait .popup',
    'click .new-button',
  ]);

Should probably have a default max time to wait, perhaps add a 3rd string param override the default.

Cannot Resolve Package When Installed from NPM

Hi there, I would like to use your project for an interactive tutorial on a business application I'm working on however for some reason it cannot resolve this package when I try to import userRoutine (as per the demo).

Not sure if this is something you've experienced yet as your demo appears to use the compiled scripts in /dist.

I'll probably just copy the built module out of /dist and use it inline in my project, but I'd much prefer to use this through npm.

Thanks!

Add workaround for the descendant css combinator (space)

Currently spaces cannot be used in the action string CSS selectors in order to preserve the ease of a single-string action command. Recommend using >> instead. Should be able to replace >> with a space after the selector portion of the action string is already split off.

Note: >> is not a great solution because >> diverges from standard CSS, but I think it's worth it because it's relatively intuitive, will not conflict with existing CSS (because >> is invalid normally), and will unblock cases where using the descendant css combinator (space) would be helpful.

Example: click table>>.row:nth-child(2)>>button Edit Row // This would click an Edit button in the 2nd row of some table, regardless of how deeply nested. The resulting selector would be table .row:nth-child(2) button.

Also update the README so this functionality is well-documented.

Add animation

Add animation to visually show what SPA Check is doing in the UI (completed in version 4.0.0)

Send input events too

e.g.: document.querySelector('.class').dispatchEvent(new InputEvent('input'));

Need to use this on the value command.

Create demo and use it as testing page

Replace the testing page with a demo, include some sort of flag or url parameter which runs fast robust tests. Display simpler demo tests. Host via GH Pages.

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.