{"id":22268729,"url":"https://github.com/paveldymkov/puppeteer-io","last_synced_at":"2026-05-06T07:36:02.681Z","repository":{"id":65478707,"uuid":"116928860","full_name":"PavelDymkov/puppeteer-io","owner":"PavelDymkov","description":"Library for tests with Puppeteer using Jest or Mocha","archived":false,"fork":false,"pushed_at":"2022-05-16T15:12:11.000Z","size":125,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-19T13:11:20.431Z","etag":null,"topics":["headless-chrome","puppeteer","testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PavelDymkov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-10T08:19:08.000Z","updated_at":"2023-09-08T17:34:58.000Z","dependencies_parsed_at":"2023-01-25T15:16:24.406Z","dependency_job_id":null,"html_url":"https://github.com/PavelDymkov/puppeteer-io","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelDymkov%2Fpuppeteer-io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelDymkov%2Fpuppeteer-io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelDymkov%2Fpuppeteer-io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelDymkov%2Fpuppeteer-io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PavelDymkov","download_url":"https://codeload.github.com/PavelDymkov/puppeteer-io/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245486358,"owners_count":20623244,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["headless-chrome","puppeteer","testing"],"created_at":"2024-12-03T11:13:40.084Z","updated_at":"2026-05-06T07:36:02.647Z","avatar_url":"https://github.com/PavelDymkov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Puppeteer-IO\n\n![tests: passing](https://raw.githubusercontent.com/PavelDymkov/puppeteer-io/master/badges/tests.svg)\n![tests with puppeteer: 14.1.0](https://raw.githubusercontent.com/PavelDymkov/puppeteer-io/master/badges/shoelace-version.svg)\n\n**Puppeteer-IO** is a library for [Puppeteer](https://github.com/GoogleChrome/puppeteer) that parallelizes code execution into two streams: the command input stream to the browser and the stream of receiving messages from the browser.\n**Puppeteer-IO** was created for writing tests, when it is necessary to check whether some code was called.\nFor this purpose, use the `console.log` call to retrieve messages from the browser.\n\n## Install\n\n```bash\nnpm i puppeteer-io\n```\n\n## Usage\n\n### React-component testing example\n\nLet's look at testing the React-component using [Jest](https://facebook.github.io/jest/). The source code of the React-component:\n\n```javascript\nimport React from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst iItem = PropTypes.shape({\n    id: PropTypes.string.isRequired,\n    text: PropTypes.string.isRequired,\n});\n\nexport default class Select extends React.Component {\n    static propTypes = {\n        items: PropTypes.arrayOf(iItem).isRequired,\n        onChange: PropTypes.func,\n    };\n\n    getChangeHandler() {\n        return ({ target }) =\u003e {\n            if (this.props.onChange) {\n                this.props.onChange(this.props.items[target.selectedIndex].id);\n            }\n        };\n    }\n\n    toOption(item, index) {\n        return \u003coption key={`id_${index}_${item.id}`}\u003e{item.text}\u003c/option\u003e;\n    }\n\n    render() {\n        return (\n            \u003cselect onChange={this.getChangeHandler()}\u003e\n                {this.props.items.map(this.toOption)}\n            \u003c/select\u003e\n        );\n    }\n}\n```\n\nNow create a page that will open in the browser to test the component.\n\n```javascript\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport Select from \"./select-component.js\";\n\nconst testItems = [\n    { id: \"0e210d4a-ccfd-4733-a179-8b51bda1a7a5\", text: \"text 1\" },\n    { id: \"ea2cecbd-206c-4118-a1c9-8d88474e5a87\", text: \"text 2\" },\n    { id: \"c812a9dc-6a54-409e-adb5-8eb09337e576\", text: \"text 3\" },\n];\n\nconsole.log(\"test-items\", testItems);\n\nfunction TestPage() {\n    const onChange = (id) =\u003e console.log(\"Select: change\", id);\n\n    return (\n        \u003cdiv\u003e\n            \u003cSelect items={testItems} onChange={onChange} /\u003e\n        \u003c/div\u003e\n    );\n}\n\nReactDOM.render(\u003cTestPage /\u003e, document.getElementById(\"application\"));\n```\n\nAnd the test case.\n\n```javascript\nconst puppeteer = require(\"puppeteer\");\nconst io = require(\"puppeteer-io\");\n\ntest(`check that id is sent to onChange callback`, async () =\u003e {\n    let browser = await puppeteer.launch();\n    let page = await browser.newPage();\n\n    await page.goto(\"http://localhost\"); // test page url\n\n    await io({\n        page,\n        async input() {\n            let select = await page.$(\"select\");\n\n            await select.focus();\n            await select.press(\"Enter\");\n            await select.press(\"ArrowDown\");\n            await select.press(\"Enter\");\n        },\n        async output({ message }) {\n            let [, secondItem] = await message(\"test-items\");\n            let selectedId = await message(\"Select: change\");\n\n            expect(selectedId).toBe(secondItem.id);\n        },\n    });\n\n    await page.close();\n    await browser.close();\n});\n```\n\n### Another example\n\nCheck whether the event handler was called.\n\n**_index.html_**\n\n```html\n\u003cinput /\u003e\n\u003cscript\u003e\n    const focusHandler = () =\u003e console.log(\"input-onFocus\");\n\n    document\n        .querySelector(\"input\")\n        .addEventListener(\"focus\", focusHandler, false);\n\u003c/script\u003e\n```\n\n**_on-focus.test.js_**\n\n```javascript\nconst puppeteer = require(\"puppeteer\");\nconst io = require(\"puppeteer-io\");\n\nlet browser, page;\n\nbeforeAll(async () =\u003e {\n    browser = await puppeteer.launch();\n});\n\nbeforeEach(async () =\u003e {\n    page = await browser.newPage();\n\n    await page.goto(\"http://localhost\");\n});\n\nafterEach(async () =\u003e {\n    await page.close();\n});\n\nafterAll(async () =\u003e {\n    await browser.close();\n});\n\ntest(`message received`, (done) =\u003e {\n    io({\n        page,\n        done,\n        async input() {\n            await page.focus(\"input\");\n        },\n        async output({ message }) {\n            await message(\"input-onFocus\");\n        },\n    });\n});\n```\n\n## Documentation\n\n`require(\"puppeteer-io\")` returns a function that takes as argument an object contains:\n\n-   `page` \u003c[Page](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page)\u003e\n    The [page](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page) in which the code is executed.\n\n-   `done` \u003c[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)\u003e\n    A callback that is called when both streams are executed.\n\n-   `input()` \u003c[async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction)\u003e\n    The command input stream to the browser\n\n-   `output(api)` \u003c[async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction)\u003e\n    The stream of receiving messages from the browser. This function provide an object contains methods:\n\n    -   `message(content: \u003cString\u003e): \u003cPromise\u003cJSONValue\u003e\u003e`\n        Promise returns an object passed from the browser by `console.log(id, data)`. You can only pass the serializable data ([more](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#jshandlejsonvalue)).\n\n    -   `error(pattern: \u003cString|RegExp\u003e): \u003cPromise\u003cString\u003e\u003e`\n        Promise returns `error.message` if the message matches the pattern.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaveldymkov%2Fpuppeteer-io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaveldymkov%2Fpuppeteer-io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaveldymkov%2Fpuppeteer-io/lists"}