Coder Social home page Coder Social logo

checkly / headless-recorder Goto Github PK

View Code? Open in Web Editor NEW
15.0K 182.0 712.0 11.83 MB

Chrome extension that records your browser interactions and generates a Playwright or Puppeteer script.

Home Page: https://checklyhq.com/headless-recorder

License: MIT License

JavaScript 71.29% HTML 1.91% CSS 1.75% Vue 25.05%
puppeteer chrome chrome-extension vue playwright

headless-recorder's Introduction

🚨 Deprecated!

As of Dec 16th 2022, Headless Recorder is fully deprecated. No new changes, support, maintenance or new features are expected to land.

For more information and possible alternatives refer to this issue.

Headless Recorder

Headless Recorder

Github Build Chrome Webstore Users Chrome Webstore Version

🎥 Headless recorder is a Chrome extension that records your browser interactions and generates a Playwright/Puppeteer script.


Headless recorder demo


Overview

Headless recorder is a Chrome extension that records your browser interactions and generates a Playwright or Puppeteer script. Install it from the Chrome Webstore to get started!

This project builds on existing open source projects (see Credits) but adds extensibility, configurability and a smoother UI. For more information, please check our documentation.

🤔 Do you want to learn more about Puppeteer and Playwright? Check our open Headless Guides


What you can do?

  • Records clicks and type events.
  • Add waitForNavigation, setViewPort and other useful clauses.
  • Generates a Playwright & Puppeteer script.
  • Preview CSS selectors of HTML elements.
  • Take full page and element screenshots.
  • Pause, resume and restart recording.
  • Persist latest script in your browser
  • Copy to clipboard.
  • Run generated scripts directly on Checkly
  • Flexible configuration options and dark mode support.
  • Allows data-id configuration for element selection.

Recorded Events

  • click
  • dblclick
  • change
  • keydown
  • select
  • submit
  • load
  • unload

This collection will be expanded in future releases. 💪


How to use?

  1. Click the icon and hit the red button.

  2. 👉 Hit tab after you finish typing in an input element. 👈

  3. Click on links, inputs and other elements.

  4. Wait for full page load on each navigation.

    The icon will switch from recording icon to waiting icon to indicate it is ready for more input from you.

  5. Click Pause when you want to navigate without recording anything. Hit Resume to continue recording.

⌨️ Shortcuts

  • alt + k: Toggle overlay
  • alt + shift + F: Take full page screenshot
  • alt + shift + E: Take element screenshot

Run Locally

After cloning the project, open the terminal and navigate to project root directory.

$ npm i # install dependencies

$ npm run serve # run development mode

$ npm run test # run test cases

$ npm run lint # run and fix linter issues

$ npm run build # build and zip for production

Install Locally

  1. Open chrome and navigate to extensions page using this URL: chrome://extensions.
  2. Make sure "Developer mode" is enabled.
  3. Click "Load unpacked extension" button, browse the headless-recorder/dist directory and select it.


Release

  1. Bump version using npm version (patch, minor, major).
  2. Push changes with tags git push --tags
  3. Generate a release using gren: gren release --override --data-source=milestones --milestone-match="{{tag_name}}"

🚨 Make sure all issues associated with the new version are linked to a milestone with the name of the tag.


Credits

Headless recorder is the spiritual successor & love child of segment.io's Daydream and ui recorder.


License

MIT

Checkly
Delightful Active Monitoring for Developers
From Checkly with ♥️

headless-recorder's People

Contributors

a631807682 avatar aofdev avatar dandv avatar dennisloska avatar dependabot[bot] avatar dolfje avatar ephetic avatar gregorkikelj avatar honey-dip avatar ianaya89 avatar jamieni avatar jeffjose avatar maxigimenez avatar mikedidomizio avatar ndom91 avatar petrogad avatar pilimartinez avatar rationalthinker1 avatar shuuji3 avatar tnolet avatar viditochani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

headless-recorder's Issues

Selector string not quoted when using data attribute

I am using the custom data attribute. In my case it's data-pweb-logical-id. When the selector is transformed to javascript there are no quotes around the value of the data attribute and the puppeteer script fails without them.

The recorder returns:
await page.waitForSelector('[data-pweb-logical-id={{dynamictable|Col1||Col1}|{cells|||Flow}}]')

And I would like it to return:
await page.waitForSelector('[data-pweb-logical-id="{{dynamictable|Col1||Col1}|{cells|||Flow}}"]')

Navigation promise placement is wonky sometimes

examples are:

  1. it comes after the navigation...
(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  
  await page.setViewport({ width: 1280, height: 694 })
  
  await page.goto('https://someurl')
  
  await page.waitForSelector('.vertical-center > .row > .col-md-offset-4 > form > .btn-primary')
  await page.click('.vertical-center > .row > .col-md-offset-4 > form > .btn-primary')
  
  const navigationPromise = page.waitForNavigation()
  await navigationPromise
  
  await browser.close()
})()
  1. There are many duplicates after one navigation. No example yet.

Does not always record goto action

When a start recording, type url and press enter, I get goto and navigation actions sometimes, but I just get navigation action most of times. So most of time I get a script which doesn't work because it isn't load an URL:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  
  const navigationPromise = page.waitForNavigation()
  
  await navigationPromise

  ....
  
  await browser.close()
})()

Sometimes I get right script:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  
  const navigationPromise = page.waitForNavigation()
  
  await page.setViewport({ width: 1920, height: 906 })
  
  await page.goto('URL')
  
  await navigationPromise

  ....  

  await browser.close()
})()

Recording does not work

I followed the instructions in the Readme and loaded the unpacked extension in Chrome. After I press record and enter an URL, the icon changes from rec to wait and stays there. Navigating to other pages does not return the icon to rec state. If I stop, nothing is recorded in the script. I used Wikipedia as test.

data-* not useful without looping through parent elements

It would help a lot if, when checking for a data- attribute of an element, to also loop through parent html-elements. Because in most cases click events are triggered on nested elements of a UI framework.
So data-* attributes dont help a lot in this cases.

integration tests failing on master

npm --version
6.4.1
node --version
v10.15.3
npm test

> [email protected] test /Users/bcleary/dev/puppeteer-recorder
> npm run unit-test && npm run e2e-test


> [email protected] unit-test /Users/bcleary/dev/puppeteer-recorder
> jest __tests__/.*.spec.js --silent

 PASS  src/content-scripts/__tests__/UIController.spec.js
 PASS  src/code-generator/__tests__/CodeGenerator.spec.js
 PASS  src/popup/components/__tests__/ResultsTab.spec.js
 PASS  src/popup/components/__tests__/RecordingTab.spec.js
 PASS  src/popup/components/__tests__/App.spec.js
 PASS  src/options/components/__tests__/App.spec.js
 FAIL  src/content-scripts/__tests__/forms.spec.js (31.767s)
  ● forms › it should load the form

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record text input elements

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record text input elements

    Evaluation failed: TypeError: Cannot read property '_getEventLog' of undefined

      at eval (eval at waitForPredicatePageFunction (:2:21), <anonymous>:3:30)
      at onRaf (__puppeteer_evaluation_script__:56:33)
      at pollRaf (__puppeteer_evaluation_script__:48:5)
      at waitForPredicatePageFunction (__puppeteer_evaluation_script__:7:18)
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at WaitTask.rerun (node_modules/puppeteer/lib/DOMWorld.js:582:65)

  ● forms › it should record textarea elements

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record textarea elements

    Evaluation failed: TypeError: Cannot read property '_getEventLog' of undefined

      at eval (eval at waitForPredicatePageFunction (:2:21), <anonymous>:3:30)
      at onRaf (__puppeteer_evaluation_script__:56:33)
      at pollRaf (__puppeteer_evaluation_script__:48:5)
      at waitForPredicatePageFunction (__puppeteer_evaluation_script__:7:18)
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at WaitTask.rerun (node_modules/puppeteer/lib/DOMWorld.js:582:65)

  ● forms › it should record radio input elements

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record radio input elements

    Evaluation failed: TypeError: Cannot read property '_getEventLog' of undefined

      at eval (eval at waitForPredicatePageFunction (:2:21), <anonymous>:3:30)
      at onRaf (__puppeteer_evaluation_script__:56:33)
      at pollRaf (__puppeteer_evaluation_script__:48:5)
      at waitForPredicatePageFunction (__puppeteer_evaluation_script__:7:18)
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at WaitTask.rerun (node_modules/puppeteer/lib/DOMWorld.js:582:65)

  ● forms › it should record select and option elements

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record select and option elements

    Evaluation failed: TypeError: Cannot read property '_getEventLog' of undefined

      at eval (eval at waitForPredicatePageFunction (:2:21), <anonymous>:3:30)
      at onRaf (__puppeteer_evaluation_script__:56:33)
      at pollRaf (__puppeteer_evaluation_script__:48:5)
      at waitForPredicatePageFunction (__puppeteer_evaluation_script__:7:18)
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at WaitTask.rerun (node_modules/puppeteer/lib/DOMWorld.js:582:65)

  ● forms › it should record checkbox input elements

    Evaluation failed: TypeError: Cannot read property '_clearEventLog' of undefined

      at __puppeteer_evaluation_script__:2:33
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:112:20)
        -- ASYNC --
      at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at Page.evaluate (node_modules/puppeteer/lib/Page.js:782:43)
      at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:112:23)
      at evaluate (src/content-scripts/__tests__/helpers.js:18:15)
      at _callee2$ (src/content-scripts/__tests__/forms.spec.js:29:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

  ● forms › it should record checkbox input elements

    Evaluation failed: TypeError: Cannot read property '_getEventLog' of undefined

      at eval (eval at waitForPredicatePageFunction (:2:21), <anonymous>:3:30)
      at onRaf (__puppeteer_evaluation_script__:56:33)
      at pollRaf (__puppeteer_evaluation_script__:48:5)
      at waitForPredicatePageFunction (__puppeteer_evaluation_script__:7:18)
      at ExecutionContext._evaluateInternal (node_modules/puppeteer/lib/ExecutionContext.js:122:13)
        -- ASYNC --
      at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:111:15)
      at WaitTask.rerun (node_modules/puppeteer/lib/DOMWorld.js:582:65)

Test Suites: 1 failed, 6 passed, 7 total
Tests:       6 failed, 23 passed, 29 total
Snapshots:   8 passed, 8 total
Time:        34.366s

Record screenshots

Record either screenshots of the visible page or a clipped part using an on-screen selector

  • use context menu to trigger
  • use short cuts to trigger

Pushing seclectors by attr(name=value) rather than div#ids

Hey guys, anyone know the level of effort to adjust the block building to select elements by attr "name" rather than id?

I am struggling with a page that dynamically assigns div IDs and it is unreliable to select by ID

from:

  await page.waitForSelector('div > .qx-widget > .qx-widget > #id_379 > div')
  await page.click('div > .qx-widget > .qx-widget > #id_379 > div')

to:

  await page.waitForSelector('div > .qx-widget > .qx-widget > [name="frmMain_pbSpecMaint"] > div')
  await page.click('div > .qx-widget > .qx-widget > [name="frmMain_pbSpecMaint"]  > div')

Does not record actions on dynamically added DOM nodes

Hello, first of all, thanks for the great extension.

I'm using it on a Vuejs app that uses v-if directives, which implies the nodes are dynamically attached to the DOM whenever the condition becomes true.

It is the case for a modal dialog that appears after clicking a button. None of the actions being performed on the modal is recorded by the extension. The workaround I found is that, opening the modal before recording actually works, which implies the problem is related to the modal being attached to the DOM during the recording.

Another workaround is substituting the v-if with v-show, which breaks performance, since everything is in the DOM at page load.

Thanks for your help!

Record basic forms

Usefulness of the plugin is very much depended on automating the time intensive parts of testing and crawling. Number one is probably filling out forms. This extension should be able to record all the things that are in a typical Bootstrap-type form:

  • select / drop downs
  • radio buttons
  • check boxes
  • text areas
  • button and link clicks

add basic events tracking

We need to track a very basic set of events through Google Analytics to see how we can make Puppeteer Recorder better.

Events:

  • Start
  • Show help
  • Show setting
  • Copy to clipboard

Not recording keystrokes

Hi!

I just came across this plugin and it worked like a charm.

One thing I noticed though is that it doesn't record keyboard input, which would be great (i added my own page.type code in where necessary, but it'd be good if you could enable the plugin to record keystrokes for you.

Thanks for this great plugin, helped me as a non webdev generate reliable selectors for my little automation task! :)

popup script has package.json content

Played with the extension for a bit last night to check out the extension and noticed the "package.json" content in the popup script. I think it may have been caused by accidentally included the "package.json" file in webpack config...

selector should always prefer ID tags over classes

currently, this is possible. A bunch of generated classes with a perfectly fine ID tag at the end. In these cases, the ID tag should "win" and the class selectors disregarded.

  await page.waitForSelector('.loCvjm > .dqCcvp > .iczaPt > .hkOTKM > #ListingSort--SortPicker')
  await page.click('.loCvjm > .dqCcvp > .iczaPt > .hkOTKM > #ListingSort--SortPicker')

Recording/binding events to <select/> elements

Hey,

so I was trying to record a dropdown menu selection. The dropdown menu consist of semantic HTML5 ( and elements). The issue is, that the recorder does not recognize the element at all. I tried to change the code in the CodeGenerator.js to register the event on a 'click' and not on a 'change' event, as it currently is, but that also did not work. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select I get this error from the finder-module: Can't generate CSS selector for non-element node type. So it seems the recorder somehow does not pass the correct element to the finder in order for it to find a selector. I am sorry for the formatting, but for some reason the Markdown is not working here and I don't know how to fix that.

Can only record once after installation, not again

Some report that they can only record one script after installation of the extension and not anymore. I can not reproduce (tried on a fresh Chrome installation + extension installation). Anyone suffering from this, please set logging in the console to "verbose" and report in this issue.

image

Add viewport detection

The viewport width / height should be detected add add as a await page.setViewport({ width: 1280, height: 800 }) stanza after spawning the first page.

This is handy because after recording, menus might be invisible as the viewport is not very wide.

Add optional page.waitForSelector() line before clicks

It is a very common scenario to have to wait for an element before you can click it. It should be possible to add a waitForSelector before click. i.e.

await page.waitForSelector('a.link')
await page.click('a.link')

This feature should be toggleable in the options pane.

Trust uniqueness of `id`s if present

Puppeteer-recorder has a special case for using a shorter selector if the target element has an id, but why not just use the id alone?

Likewise, if a long selector contains any ids, why not drop the whole prefix up to the last id?

Allow the recording of hover or mouse activities

seems the mouse movement are not recorded. so therefore, the hover triggered dom won't be able to get triggered... is there way to enable that recording, or its something can not be done with puppeteer as a hard limit?

really like the tool able to pick up the dom correctly, way better than my guessing game. ha.
keep it up!

Support for page.waitForNavigation

When there's a navigation event (which it looks like the plugin is sensitive to), the outputted script should probably do:

await page.waitForNavigation()

Otherwise the "next" task might get lost in execution. This can be tricky to orchestrate since you want to have this happen immediately after a click, but not await the click event that causes the navigation, so it's a bit awkward.

https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions

Feature Proposal: Targeting attributes through data-id vs nested selectors.

First off, THANK YOU for a fantastic chrome extension to help make lives easier when working through automating new screens. It's been a fantastic addition to our testing process!

One thing that I've been working on is adding the ability to target elements based on a configurable data-* attribute.

The reasoning behind this is within our SPA, we use dynamic css class names that are unique and allow for no global bleeding of CSS classes (components are then bundled together with their classes). This leads to new class names whenever content changes within them and thus would break tests.

To fix this, I've built in data-test-id attributes (stripped out in prod via webpack) but used in automated test builds for better targeting: [data-test-id=my-element].

At present, I've forked the project and have begun implementing it but would love to commit that change back to this repo if the maintainers see this as something they would like to include in the project.

Thank you for your consideration and for open sourcing this fantastic extension.

Readme update for security concerns

Hi,

Do you think y'all could add a privacy / security statement in the README?

Something along the lines of it saves locally and doesn't upload anywhere?

Support for iframe click events

I would love to see support for recording events from iframes and populating the script with the appropriate frame selection.
const frames = await page.frames(); const curFrame = frames.find(f => f.name() === 'activeFrame'); await curFrame.click('#selector')

Recording actions on a Chrome-Extension

On hitting record, then loading a Chrome-Extension URL (for example, the settings page of a Chrome-Extension), doing actions on this page and going back to Puppeteer Recorded, there is no script generated.

This might be related to issue #22

Layout of code view is glitchy

The overflow is not perfect:

  • code should scroll up, showing the last recorded statements.
  • right side overflow is wonky

image

Add more elements

We want to add more elements like

div
img
span
h1
h2
h3
h4
h5
h6
label

This however brings the problem of double triggered events. An a nested in a span can generate double click events for instance.

Therefore we need to de double events in a somewhat intelligent way.

options.prepare is not a function

hi , im trying ti record browser activity on the server

her eis simplified version of my code


const puppeteer = require('puppeteer');
const { record } = require('puppeteer-recorder');
var path = 'C:\\wamp64\\www\\home_robot\\';

init_puppeteer();

const global_browser  ; 
async function init_puppeteer() {
        global_browser = await puppeteer.launch({headless: false , args: ['--no-sandbox', '--disable-setuid-sandbox']});

    check_login()
};


async function check_login()
{

    try {
        const page = await global_browser.newPage();
        await page.setViewport({width: 1000, height: 1100});
        await record({
            browser: global_browser, // Optional: a puppeteer Browser instance,
            page: page, // Optional: a puppeteer Page instance,
            output: path + 'output.webm',
            fps: 60,
            frames: 60 * 5, // 5 seconds at 60 fps
        });

        await page.goto('https://www.example.cob', {timeout: 60000});
        await page.close();
    }
    catch (e) {
        console.log(' LOGIN ERROR ---------------------');
        console.log(e);
    }
}

but when i run it i get this error



 LOGIN ERROR ---------------------
TypeError: options.prepare is not a function
    at module.exports.record (C:\wamp64\www\home_robot\node_modules\puppeteer-recorder\index.js:8:17)
    at check_login (C:\wamp64\www\home_robot\home.js:178:15)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Recording won't grab typing unless a tab has been pressed.

So basically I have a typeahead component in react. I'm trying to test that when I type something the list appears and I can click a button in that list. It registers that I clicked the input to focus on it, but not that I typed anything because I didn't hit tab to navigate away. Can we change it so that when I lose focus from that input it adds the text?

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.