Home Reference Source

Behaviors

Quick Start

Requirements: Node.js

To use this project you must first install its dependencies

$ yarn install
# or "npm install"

Once you have installed the dependencies you are ready to start using the project

Via Docker

To build the behaviors docker image (webrecorder/behaviors:latest) execute docker-compose build.

The image created is suitable for building behaviors and running the behavior api server.

The default configuration of the image is to run the api server, however you can substitute the default command with any of the cli commands listed previously.

For more information please consult the provided Dockerfile and docker-compose.yml files.

Behaviors

Format

A behavior is simply a JavaScript file that exposes the means to perform its series of actions in a page and some information (metadata) about itself.

With this in mind, every behavior is expected to be JavaScript module that

An example of the expected format behavior is shown below

// means to perform the series of  actions
export default async function* myBehavior(cliAPI) { ... }

// information about the behavior
export const metadata = { ... };

// flag indicating this file is a behavior ready to be used
export const isBehavior = true;

// optional function to be called after each step of the behavior
export function postStep(rawBehaviorStepResults) { ... }

In the example above, the behavior exposes the means to perform its actions using the export default keywords.

The export default keywords indicate that whatever follows is the primary export of the module and what ever is default export of a behavior is used to run the behavior.

Any additional information that the behavior wishes to be expose using the export keyword and is shown in the example above with the final two required named exports metadata and isBehavior.

Please note that isBehavior named export is used to indicate that this behavior is ready to be used.

If the isBehavior export is missing then the provided tools will not recognize the behavior as being ready and will not use the behavior.

Likewise, if the behavior does not have a default export and does not export metadata and isBehavior, the tools will not consider the behavior as valid.

The optional export postStep is a function called after each action (step) of the behavior to convert the yielded results into the expected format.

It is recommended that you use the library function lib.buildCustomPostStepFn if you want to perform some kind of action after each behavior step that is not directly tied to the running of the behavior.

export const postStep = lib.buildCustomPostStepFn(() => { ... });

Metadata

A behaviors exported metadata is used to

  • describe how it should be matched to the pages it is written for
  • provide an overview of what it does
  • have a more specific name associated with it when querying for it using the behavior api
  • embed any additional information about the behavior

And every exported metadata object is expected to have the following properties

  • name (string): the name for your behavior to be used when querying the behavior API for it by name
  • description (string): a description for the behavior
  • match (object): how the behavior will be matched to the page(s) it is written for

Of the expected metadata properties, the match object has two variations and is shown below in the context of two valid metadata exports.

// variation 1
export const metadata = {
  name: 'the name of your behavior',
  match: {
    regex: /an regular expression dictating the URL the behavior will run on/,
  },
  description: 'an description of what your behavior does',
};

The first variation, shown above, defines a single property regex that is an JavaScript RegExp.

The behavior using variation one is considered matched to an URL when the regular expression, defined in the regex property of match, matches the URL.

The second variation, shown below, has two properties base (RegExp) and sub (Array<RegExp>).

The base regular expression is used as a generic test and if it matches a URL the regular expressions in the sub array will be tested against the same URL.

The behavior is considered matched to a URL when the base regular expression matches the URL and one of the sub regular expressions also matches the URL.

// variation 2
export const metadata = {
  name: 'the name of your behavior',
  match: {
    regex: {
      base: /an regular expressions dictating the base URL the behavior will run on/,
      sub: [
        /an array of regular expressions dictating more specific parts of the base URL the behavior will run on/,
      ],
    },
  },
  description: 'an description of what your behavior does',
};

Behavior Implementation Overview

The primary reasons that a behaviors default export is required to be an async generator function or a function returning an async iterator are

  • Async generators are a native JavaScript feature cross the major browser
  • They provide a simple way to run the behavior via in the browser and via browsertrix
  • Allow information about the behavior, its state, to be easily reported to behavior runners

However we understand this requirement, namely behaviors as async generators, may be a new JavaScript idiom for some and for the remaining portion of this section give a high level overview on how to write a behavior under this requirement.

Now consider the following example shown below which is a behavior living in the in the "behaviors" directory of this project for all pages of myAwesomeWebSite.com.

Please note that there is no code in the body of the myBehavior function, this is ok as all the remaining code examples should be assumed to be inside function where the comment "behavior code" is currently.

Also note that their exists a cli command for new behavior creation that will fill out much of the boiler plate shown in the code section below

import * as lib from '../lib';

export default async function* myBehavior(cliAPI) {
  // behavior code
}

export const metadata = {
  name: 'myBehavior',
  match: {
    regex: /^(?:https?:\/\/(?:www\.)?)?:myAwesomeWebSite.com.*$/,
  },
  description: 'It does really cool stuff',
};

export const isBehavior = true;

As you will have already noticed by looking over the documentation for the behaviors standard library that many of the functions returns Promises.

Now without turning into a JavaScript tutorial the only thing you need to know about promises is that they can be awaited, that is to say you can await for their completion.

This comes in handy when you want to wait for the the documents state to become ready since the pages of myAwesomeWebSite.com take a long time to load and can be done as easily as shown in step 1

// step 1
await lib.domCompletePromise();

Now we know that the browser has fully parsed the page and we can safely start operating on the page.

But first we should let ourselves know that we are good to go by reporting some state and is done by yielding a value as shown in step 2

// step 1
await lib.domCompletePromise();
// step 2
const state = { videosPlayed: 0 };
yield lib.stateWithMsgNoWait('Document ready!', state);

The function lib.stateWithMsgNoWait indicates to the behavior runner that the behavior has an updated to report and that it does not have to wait.

If the behavior was being run by browsertrix and the other function lib.stateWithMsgWait was used, browsertrix would have waited until the HTTP requests made by the page had died down (no request made for set period of time) but since we use the no wait variant we know no wait will be made.

When you yield a value from the behavior you can consider the behavior paused until the runner initiates an the next action.

If a wait was indicated using the lib.stateWithMsgWait and the behavior is being run by browsertrix no more actions would be initiated until the pages network (amount of HTTP requests made) become idle (no more requests made for a set period of time).

Additionally, it should be noted that the second argument supplied to lib.stateWithMsgNoWait is optional but useful for reporting to yourself more detailed information about the state of your behavior.

Continuing on with the creation of our behavior, let us assume that the page that the behavior is operating in has a list videos we want to play.

We can accomplish this as shown in step 3

// step 1
await lib.domCompletePromise();
// step 2
const state = { videosPlayed: 0 };
yield lib.stateWithMsgNoWait('Document ready!', state);
// step 3
for (const videoListItem of lib.childElementIterator(lib.id('videos'))) {
  // videoListItem is a child of the element with id == 'videos'
  // that has a video as child element
  const videoWasPlayed = await lib.selectAndPlay('video', videoListItem);
  if (videoWasPlayed) {
    // increment our states counter for number of videos played
    state.videosPlayed += 1;
    // let ourselves know we played a video
    yield lib.stateWithMsgNoWait('Played a video!', state);
  } else {
    yield lib.stateWithMsgNoWait('Failed to play a video using the standard DOM methods', state);
  }
}
return lib.stateWithMsgNoWait('Done!', state);

In step three we use the function childElementIterator that returns an iterator over the child elements of the supplied parent element and then for each child of the element with `id="videos" we

  • select the video element that is a descendant of the videoListItems and play the video
  • increment the number of videos played in our behaviors state
  • let ourselves know that we played a video

Also seen in step 3 is the usage keyword yield in combination with * or yield *.

yield * means that we are yielding another generator, that is to say all actions of the generator are to be treated as if we yielded them ourselves.

In short step 3 can be described as playing a video contained in every child of the element with id == video and once we have played all the videos on the page return a message with our final state from the behavior.

This completes the mini-tutorial on how to create behaviors.

The full behavior is shown below

import * as lib from '../lib';

export default async function* myBehavior(cliAPI) {
  // behavior code
  // step 1
  await lib.domCompletePromise();
  // step 2
  const state = { videosPlayed: 0 };
  yield lib.stateWithMsgNoWait('Document ready!', state);
  // step 3
  for (const videoListItem of lib.childElementIterator(lib.id('videos'))) {
    // videoListItem is a child of the element with id == 'videos'
    // that has a video as child element
    const videoWasPlayed = await lib.selectAndPlay('video', videoListItem);
    if (videoWasPlayed) {
      // increment our states counter for number of videos played
      state.videosPlayed += 1;
      // let ourselves know we played a video
      yield lib.stateWithMsgNoWait('Played a video!', state);
    } else {
      yield lib.stateWithMsgNoWait('Failed to play a video using the standard DOM methods', state);
    }
  }
  return lib.stateWithMsgNoWait('Done!', state);
}

export const metadata = {
  name: 'myBehavior',
  match: {
    regex: /^(?:https?:\/\/(?:www\.)?)?:myAwesomeWebSite.com.*$/,
  },
  description: 'It does really cool stuff',
};

export const isBehavior = true;

Development Workflow

Automated

The simplest way to both develop and run a behavior on the target page is to use the provided behavior runner cli and a run configuration file (more details).

To help you get started a behavior run configuration file, behavior-run-config.yml found at the root of this project, has been provided for you.

By using the provided configuration file all that is required is to change two fields:

  • behavior: the path to your new behavior in the behavior directory of this project
  • url: the url of the page your behavior should be run in

Once you have changed those two you fields you can start the build and run process by either executing one of the following from the root directory of this project

  • ./bin/cli runner -c behavior-run-config.yml
  • ./bin/cli-runner -c behavior-run-config.yml

The command will launch a Chrome/Chromium browser installed on your computer, build the behavior, and then run it until completion.

While the behavior is being run or the behavior has run to completion and a change has been detected to the behavior or any of the files it includes, it will be rebuilt and re-run automatically.

Manual

To build the behavior execute the following command ./bin/cli-behaviors -b ./behaviors/<path to your behavior>. Once the command exits the behavior ready to be run can be found at ./dist/<behavior name>.js or you can copy the path displayed in the output of the build command.

The next step is to copy the contents of the generated file into the browser and run it.

The generated file contains JavaScript that will setup the behavior for running using an utility class exposed on window as $WBBehaviorRunner$.

Shown below are the ways provided for you to manually run the behavior by the utility class.

/* automatic running, chose 1 method */
(async () => {
  for await (const state of $WBBehaviorRunner$.autoRunIter()) { 
    console.log(state); 
  }

  /* or */ 
  await $WBBehaviorRunner$.autoRun({logging: true});

  /* or */ 
  await $WBBehaviorRunner$.autoRunWithDelay({logging: true});
})();

/* manually initiate each step of the behavior */
(async () => {
  while (true) {
    const state  = await $WBBehaviorRunner$.step();
    console.log(state);
    if (state.done) break;
  }
})();

The autoRunIter function accepts a single optional argument delayAmount (number), which is a time value in milliseconds that will be applied after each action (step) of the behavior.

Both the autoRun and autoRunWithDelay methods accept a single optional argument options (object) with one exception, autoRunWithDelay defaults to applying a one second delay after each action if no delay was specified.

The full configuration options for these two methods are displayed below

  • delayAmount (number, defaults to 1000): Time value in milliseconds representing how much time should be waited after initiating a behavior's step
  • noOutlinks (boolean, defaults to true): Should the collection of outlinks be disabled when running the behavior
  • logging (boolean, defaults to true): Should information the behavior sends be displayed

If you use one of the three way to "automatically" run the behavior and you wish to pause it while it is running set window.$WBBehaviorPaused to true and to un-pause it set window.$WBBehaviorPaused to false.

Build System

Overview

The behavior build process has three phases

  • Initialization
  • Collection
  • Building

Initialization

Initialization has three steps

  1. Ultimate build configuration
  2. Building what resolution
  3. Ensuring the necessary build directory structure exists

Ultimate build configuration

The ultimate build configuration is created in combination with user supplied cli options using the following steps

  1. If a config was specified using -c, --config it is used
  2. If the default config exists in the current working directory of the commands it used
  3. Otherwise the path to the behavior file or dir (-b, --build [fileOrDir]) is used and the six config values are set to the project defaults

When a config file is used each of the six values from the config file are resolved as follows

  • if the key exists and value is relative, make absolute by resolving it against the directory containing the config file
  • if the key exists and is absolute, use key value
  • if key does not exist use project default value
    • build, dist: <directory containing config>/<name>
    • lib, tsconfig: projects default value
    • metadata: placed in current working directory

Once the ultimate build configuration has been created, the build process proceeds to the next step.

Building what resolution

The determination for what is being built is done using the value for the -b, --build cli option and that value can be one of two types

  • boolean: build all behaviors found in the value for the behaviors key from the supplied build config
  • string: path to a directory containing behaviors or a single behavior to be built

When the value for build is boolean

  • If the directory supplied via the behaviors config key exists, the what is being built is that directory and the initialization process contains to the next step
  • Otherwise the directory supplied via the behaviors config key does not exist the build process is ended

When the value for build is a string and an absolute path

  • If the path exists, the what is being built is that directory or file and the initialization process contains to the next step
  • Otherwise the path does not exist the build process is ended

When the value for build is a string and an relative path, it is resolved in the following order

  1. the value as is resolved using node's relative path resolution algorithm. Note this value is used by other steps if previous ones fail and is denoted as resolvedPath
  2. the value as is joined with the supplied configs behavior dir or projects default behavior dir
  3. the value as is joined with the the current working directory
  4. resolvedPath joined with the supplied configs behavior dir or projects default behavior dir
  5. resolvedPath joined with the current working directory

If any of the absolute paths described above exist, the what is being built is the resolved path and the initialization process contains to the next step otherwise the build process is ended

Ensuring the necessary build directory structure exists

The final step in the initialization process is to ensure that the build and dist directories exist.

These values may differ from the names used previously only when they are supplied by the user in a build config file.

The build directory is used to hold intermediate files used by the build system in order to setup the behavior for final building and usage by other tools such as our own running system.

Any setup in order to facilitate running the behavior is done here.

The dist directory is where the built, bundled, behaviors are placed alongside their metadata if configured to do so.

Collection

The collection phase operates in one of two modes

  • single behavior: when the what is being built path resolves to file
  • multi-behavior: when the what is being built path resolves to a directory

The primary difference between modes is that multi-behavior mode considers every file contained in the directory and its descendant directories.

Both modes use the same means in determining if a file is indeed a behavior which is as follows

  • the file is an es module
  • has a metadata or metaData named export
  • has a isBehavior named export

Once the behavior(s) have been collected a report is printed stating how many behaviors were found and if any of the files considered partially met the requirements for collection.

Note: Both the collection and building phases share modes with the mode operating under set by the collection phase.

Building

The building phase can be described in the following steps:

  1. Extract behaviors metadata
  2. Create the behavior's intermediate file in the configured build directory
  3. Use build behavior using rollup, built behavior placed in configured dist directory
  4. Once all behaviors have been built generate behavior metadata.

The previous steps are applied to all behaviors returned by the collection phase

CLI

A cli is provided to help you use this project.

The commands available to you are displayed below

$ ./bin/cli --help

Usage: cli <command> [options]

Options:
  -V, --version                        output the version number
  -h, --help                           output usage information

Commands:
  api [options]                        Start the behavior api sever
  behaviors [options]                  Build and or validate behaviors, or generate their metadata
  newBehavior [options]                Create a new behavior
  runner [options] <path-to-behavior>  Run and or build a behaviors
  stdlib [options]                     Commands specific to working with the behavior's std library
  help [cmd]                           display help for [cmd]

The cli provides four commands api, behaviors, runner, and stdlib and each command has its own options.

API command

The api command allows you to start a server for serving your built behaviors.

To run the behavior api server execute ./bin/cli api --build-behaviors.

This will start the api server after all behaviors provided by wr-behaviors have been built.

If you have already built the behaviors using the behaviors command provided by the cli then you may omit the --build-behaviors flag.

Once the server is started the following endpoints are available

  • /behavior?<match how>: endpoint for retrieving a behavior's code
  • /info?<match how>: endpoint for retrieving a behavior's metadata
  • /info-list?<match how>: endpoint for retrieving the metadata for all behavior's that match
  • /info-all: endpoint for retrieving the metadata for every behavior

match how

  • name=<name of the behavior>
  • url=<URL of page a behavior matches>

The full options that available for use with this command are show below.

$ ./bin/cli api --help

Usage: cli-api [options]

Options:
  -V, --version                        output the version number
  -p, --port [port]                    The port the api server is to bind to (default: 3030)
  -h, --host [host]                    The host address the server is listen on (default: "127.0.0.1")
  -b, --behaviorDir [behaviorDir]      The path to the directory containing the build behaviors (default: "<cwd>/dist")
  -m, --behaviorMetadata [medataPath]  The path to the behavior metadata (default: "<cwd>/dist/behaviorMetadata.js")
  --build-behaviors                    Should the api server build the behaviors for starting up
  -w, --workers [numWorkers]           How many behavior lookup workers should be spawned (default: 2)
  -h, --help                           output usage information

Some configuration of the api server can be done via the environment variables listed below

  • BEHAVIOR_API_HOST: the host the api server will use (e.g. 127.0.0.1)
  • BEHAVIOR_API_PORT: the port the api server will listen on (e.g. 3030)
  • WR_BEHAVIOR_DIR: path to the directory containing the built behaviors
  • WR_BEHAVIOR_METADATA_PATH: path to the behavior metadata file
  • BUILD_BEHAVIORS: should the api server build the behaviors before starting
  • NUM_WORKERS: how many lookup workers should be spawned

Build command

To build the behaviors made available by the project execute ./bin/cli behaviors -b.

This will build the behaviors using the behavior config file located in the root of this project.

The built behaviors, along with a behavior metadata file (behaviorMetadata.js), can be found in the dist directory which will be created for you if it does not exist in the root of this project.

The full options that available for use with this command are show below.

$ ./bin/cli build --help

Usage: cli-build [options]

Options:
  -V, --version                    output the version number
  -v, --validate [fileOrDir]       
  -c, --config [configPath]        Path to the behavior config file (default: "<cwd>/dist/behavior-config.yml")
  -b, --build [fileOrDir]          Build a behaviors or all behaviors contained within a directory (default: true)
  -w, --watch [behaviorFileOrDir]  Watch the files, and their imports, in the build directory for re-bundling on changes (placed in dist directory)
  --metadata [dumpDir]             Generate behavior metadata, optionally supplying a path to directory where metadata is to be placed. Defaults to current working directory
  -h, --help                       output usage information

The config file has six keys and should specified in the config as key: value

  • behaviors: path to the directory containing the un-built behaviors
  • lib: path to the directory containing the provided behavior library or own library
  • build: path to the directory where the intermediate files will be placed (for running using Webrecorders system)
  • dist: path to directory where the fully built behaviors
  • tsconfig: path to the typescript configuration file used to provide behavior inspection and validation
  • metadata: path to where the behaviors metadata will be placed (either full path to file or directory path)

Note: Values can be relative path values as long as they are relative to the directory containing the config file.

A default is provided for you and can be found in the root of the project <path to project>/behavior-config.yml and is the config file this command looks for (in the current working directory) if one is supplied using the -c, --config option.

When using the default config file this command can be used to build all behaviors using ./bin/cli behaviors -b otherwise, you will need specify your own config ./bin/cli behaviors -c <path to your config> -b

For more details concerning the internals of the build process consult the documentation for the build system.

New behavior command

The newBehavior command provides a simple way to create a new behavior by generating a new file in the behavior directory containing the required boiler plate.

Executing ./bin/cli newBehavior awesomeBehavior will create a new behavior file awesomeBehavior.js located in the behavior directory.

The full options that are available are displayed below.

$ ./bin/cli newBehavior 
Usage: cli-newBehavior [options] <behavior file name>

Options:
  -V, --version               output the version number
  -d, --dir <directory name>  The new behavior will be created in the supplied directory name within the behaviors directory
  -h, --help                  output usage information

Runner command

The runner command allows you to automatically run a behavior on a specified URL using a Chrome/Chromium browser installed on your machine.

The full options that are available are displayed below.

$ ./bin/cli help runner

Usage: cli-runner [options] [path-to-behavior]

Options:
  -V, --version                                output the version number
  --build-config [behavior build config path]  Path to the behavior config file (default: "<cwd>/behavior-config.yml")
  -c, --config [run config path]               Path to a behavior's run config file
  -r, --run                                    Builds and runs the behavior
  -w, --watch                                  Watches the behavior for changes rebuilding and running the behavior on change
  --run-built                                  Runs a previously built behavior
  -s, --slowmo <amount>                        How much slow mo (delay) should be used between behavior steps
  -t, --run-timeout <amount>                   Maximum amount of time a behavior will run
  -e, --chromeEXE <chrome executable>          The chrome executable to be launched rather than attempting to discover / choose the best version of chrome installed
  -u, --url <url>                              URL of the page to run the behavior on
  -h, --help                                   output usage information

Please note that in order to provide automatic running of behaviors, this command must be able to launch the Chrome/Chromium browser. In other words, an already running instance of Chrome/Chromium can not be used.

The simplest way to use this command is through the usage of a config file (yaml format) and can be supplied using the -c or --config flags like so ./bin/cli runner -c <path to run config.yaml>.

An example run config is provided for you and can found in the root of this project (behavior-run-config.yml).

The config file has seven keys and should specified in the config as key: value

  • buildConfig (required): path to the behavior build config
  • behavior (required): path to the behavior to be run
  • url (required): the URL the behavior will be run on
  • mode (optional): The available modes are
    • build-watch: build and run the behavior, rebuilds and restarts the behavior on changes to the behavior
    • build: build and run the behavior once (default mode)
    • built: just run the previously built behavior
  • chromeEXE (optional): Chrome/Chromium executable path or command name to be used to launch (defaults to finding acceptable installed executable)
  • timeout (optional): time value in seconds indicating the maximum length of time the behavior will run
  • slomo (optional): time value in seconds indicating how long to wait before initiating the next action of the behavior

STDLIB command

The stdlib command exists as an utility for generating the provided behavior utility library's index.js file or to create a bundle of all provided library function for debugging.

The file name of the generated debug script is libOnWindow.js and is placed in root dir of the project.

The full options that are available are displayed below.

$ ./bin/cli help stdlib

Usage: cli-stdlib [options]

Options:
  -V, --version   output the version number
  --gen-index     Generate the behavior's standard library's index file
  --debug-script  Generate a script that exposes the entirety of the behavior's standard library on window
  -h, --help      output usage information

Pre-made Behaviors

Autoscroll

Applies to

Pages that do not have a predefined behavior for them

Behavior

Automatically scroll down the page and captures any embedded content. If more content loads, scrolling will continue until autopilot is stopped by user.

Specifics

The discovery of media is done by considering the rendered HTML of page at the current scroll position and the playing of the discovered media is done using operations defined for HTML media elements. If the page requires a more specific action to be performed in order to play its media, the behavior may fail to play the media and in this case, a more specific behavior should be made in order to handle this condition.

Instagram

Gotchas

Instagram changes their CSS class names frequently which can potentially cause the behaviors to not be able to view/play media content until they are updated.

Video posts require application logic to be played consistently. Gifs are shown via the video element and actual videos are streamed.

Note data request politeness (1 img = 4 requests)

Stories

Requires the viewer to be logged in

Logged in state detected if the “logged-in” CSS class is present or the login/sign-up element are not present

User (not own feed)

Updated: 2019-07-15T22:29:05

Applies to

  • https://(www.)instagram.com/[user name](/)
  • https://(www.)instagram.com/[user name](/?query-string)
  • https://(www.)instagram.com/[user name](/tagged)(/)

Behavior

  • View stories if able
  • View each post currently visible
  • If not stopping condition: wait for more rows indefinitely*

Viewing stories

As previously mentioned, a logged in user. If there are selected stories (profile picture is clickable) they are viewed first If there are normal stories to be viewed they are viewed

Viewing posts

Video post (gif, traditional video)

  • video is played and a wait for the user agent to determine if the video can play through all the way is done

Photo post

  • no “special” action other than view

Multiple media post

  • each part of the multi-post is viewed
  • if video media is contained the video post action is performed before moving to the next part
  • otherwise photo post action is performed

All post types

  • all comments and replies to comments are loaded

Stopping condition

Since instagram is a react application we attempt to extract the “redux store” in order to determine the number of posts by the user and to listen for application state changes that indicate if there are additional “pages” (more posts) to be retrieved.

If extraction of the “redux store” fails or application internals have changed we fall back to a rudimentary post counting scheme. When not using store the wait for more post rows to be rendered is limited to 1 minute

The completion condition can be expressed as follows Store extraction has not failed: There are no more pages to be retrieved and the current row of posts does not have a next sibling Store extraction failed: The number of posts viewed is >= number of posts by the user and the current row of posts does not have a next sibling

Individual Post

Applies to

  • https://(www.)instagram.com/p/[post-id](/)

Behavior The actions of this behavior are described in the Viewing posts section of the Instagram User behavior

Own Feed

Note: Requires logged in viewer

Unlike viewing of some other users posts the viewing of own feed posts is limited due to instagram not displaying the viewed post in a popup rather you are taken to post page

Applies to

  • https://(www.)instagram.com(/)

Behavior

View stories if any are to be had

For each rendered post:

  • perform actions described in the Viewing posts section of the Instagram User behavior with one exception, comments cannot be viewed If stopping condition not met wait for more posts to be loaded at maximum 45 seconds

Stopping condition

The currently viewed post has no next sibling after 45 seconds

Twitter

Gotchas

Tweet embeds although sometimes viewable inline by clicking on them are shown using an iframe that the behavior does not have access to

Audio video tweets are streamed and if the media is of significant length waiting for them to become fully loaded may take the entire length of the video or a significantly long period of time (5+ minutes)

Timeline

Applies to

  • https://(www.)twitter.com(/) -- Note this requires logged in
  • https://(www.)twitter.com/[user-name](/)

Behavior

If the viewed page is marked as sensitive, reveal page

For each rendered tweet

  • If tweet marked as sensitive reveal it
  • If tweet has video play it

Open tweet

  • If tweet has replies or apart of thread view comments thread parts

If stopping condition is not met wait for more tweets to be loaded

Stopping condition

The currently viewed tweet does not have a sibling and the pre-rendered stream end or stream failed are made visible

HashTags

Applies to

  • https://(www.)twitter.com/hashtag/[hash-tag](remaining-URL-parts)*

Behavior

For each rendered tweet

  • If tweet marked as sensitive reveal it
  • If tweet has video play it
  • Open tweet
    • If tweet has replies or apart of thread view comments thread parts

If stopping condition is not met wait for more tweets to be loaded and repeat

Stopping condition

The currently viewed tweet does not have a sibling and the pre-rendered stream end or stream failed are made visible

Youtube Video

Applies to

  • https://(www.)youtube.com/watch?v=[remaining-URL-parts]+

Behavior

Loads the videos additional information

Plays the video

Clicks show more replies until all replies have been loaded (if there were replies)