onChange
, and it is necessary to test that for some user actions a callback function will be called with the expected parameters passed. For this, the Puppeteer-io library will be used. But first, consider a small example on html and pure javascript without binding to libraries or frameworks ...addEvent
, which hangs an event handler on the elements by a selector. You need to write a test that will ensure that the handler is invoked on an event. Create the index.html file: <button> </button> <script> function addEvent(selector, eventType, handler) { let elements = document.querySelectorAll(selector); Array.prototype.forEach.call(elements, element => { element.addEventListener(eventType, handler, false); }); } addEvent("button", "click", event => console.log("Button.click")); </script>
console.log
, passing an action identifier string, the receipt of which means that the test was successful. Now create the index.html.test.js file, which will contain the test code for the Jest: const puppeteer = require("puppeteer"); const io = require("puppeteer-io"); test(`addEvent() `, async () => { let browser = await puppeteer.launch(); let page = await browser.newPage(); await page.goto(`file://${__dirname}/test.html`); await io({ page, async input() { await page.click("button"); }, async output({ message }) { await message("Button.click"); } }); await page.close(); await browser.close(); });
input()
function controls the browser, for example, clicks on elements or simulating keyboard input, while in output(api)
, data from the browser is obtained and processed. In this case, the message
function is used, to which the string identifier of the expected message is passed. If console.log
with such an identifier is not called in the browser, the test will hang and the Jest will consider it failed. import React from "react"; import PropTypes from "prop-types"; const iItem = PropTypes.shape({ id: PropTypes.string.isRequired, text: PropTypes.string.isRequired }); export default class Select extends React.Component { static propTypes = { items: PropTypes.arrayOf(iItem).isRequired, onChange: PropTypes.func }; getChangeHandler() { return ({ target }) => { if (this.props.onChange) { this.props.onChange(this.props.items[target.selectedIndex].id); } }; } toOption(item, index) { return <option key={`id_${index}_${item.id}`}> {item.text} </option> } render() { return <select onChange={this.getChangeHandler()}> {this.props.items.map(this.toOption)} </select> } }
import React from "react"; import ReactDOM from "react-dom"; import Select from "path-to/select-component.js"; const testItems = [ { id: "0e210d4a-ccfd-4733-a179-8b51bda1a7a5", text: "text 1"}, { id: "ea2cecbd-206c-4118-a1c9-8d88474e5a87", text: "text 2"}, { id: "c812a9dc-6a54-409e-adb5-8eb09337e576", text: "text 3"} ]; // console.log("test-items", testItems); function TestPage() { const onChange = id => console.log("Select: change", id); return <div> <Select items={testItems} onChange={onChange} /> </div> } ReactDOM.render(<TestPage />, document.getElementById("application"));
console.log
: the first is the id, and the second argument is the data. Now we will write the test code: const puppeteer = require("puppeteer"); const io = require("puppeteer-io"); test(` onChange id`, async () => { let browser = await puppeteer.launch(); let page = await browser.newPage(); await io({ page, async input() { await page.goto("http://localhost:8080"); let select = await page.$("select"); await select.focus(); await select.press("Enter"); await select.press("ArrowDown"); await select.press("Enter"); }, async output({ dataFromMessage }) { let [,secondItem] = await dataFromMessage("test-items"); let selectedId = await dataFromMessage("Select: change"); expect(selectedId).toBe(secondItem.id); } }); await page.close(); await browser.close(); });
page.goto
waiting for the page page.goto
event, and by that time the console.log("test-items", testItems)
already completed and the message will not be received. To obtain data, use the dataFromMessage
function, which returns the second argument passed to console.log
. When the test data is received, you can wait for the selected id, and compare the result with the expected. Functionality tested. <script> throw new Error("test-error"); </script>
error
, the error
function will be used, which takes a string or a regular expression as a parameter to search for an error with the corresponding text in the message
property, and returns the full text of the error. A test that will verify that an error has occurred on the page: const puppeteer = require("puppeteer"); const io = require("puppeteer-io"); test(`, `, async () => { let browser = await puppeteer.launch(); let page = await browser.newPage(); await io({ page, async input() { await page.goto(`file://${__dirname}/index.html`); }, async output({ error }) { await error("test-error"); } }); await page.close(); await browser.close(); });
Source: https://habr.com/ru/post/346676/
All Articles