puppeteer/assets/js/a86426a3.0dbc4e9c.js
release-please[bot] 5cd3979408 deploy: af9aebed33
2023-12-13 10:20:54 +00:00

2 lines
12 KiB
JavaScript

/*! For license information please see a86426a3.0dbc4e9c.js.LICENSE.txt */
"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[51247],{36244:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var r=t(85893),s=t(11151);const i={},c="Puppeteer Angular Schematic",d={id:"integrations/ng-schematics",title:"Puppeteer Angular Schematic",description:"Adds Puppeteer-based e2e tests to your Angular project.",source:"@site/../docs/integrations/ng-schematics.md",sourceDirName:"integrations",slug:"/integrations/ng-schematics",permalink:"/next/integrations/ng-schematics",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Integrations",permalink:"/next/category/integrations"},next:{title:"Experimental WebDriver BiDi support",permalink:"/next/webdriver-bidi"}},o={},l=[{value:"Getting started",id:"getting-started",level:2},{value:"Options",id:"options",level:3},{value:"Creating a single test file",id:"creating-a-single-test-file",level:2},{value:"Running test server and dev server at the same time",id:"running-test-server-and-dev-server-at-the-same-time",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Sandbox",id:"sandbox",level:3},{value:"Unit Testing",id:"unit-testing",level:3},{value:"Migrating from Protractor",id:"migrating-from-protractor",level:2},{value:"Browser",id:"browser",level:3},{value:"Query Selectors",id:"query-selectors",level:3}];function a(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"puppeteer-angular-schematic",children:"Puppeteer Angular Schematic"}),"\n",(0,r.jsx)(n.p,{children:"Adds Puppeteer-based e2e tests to your Angular project."}),"\n",(0,r.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,r.jsx)(n.p,{children:"Run the command below in an Angular CLI app directory and follow the prompts."}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"Note this will add the schematic as a dependency to your project."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"ng add @puppeteer/ng-schematics\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Or you can use the same command followed by the ",(0,r.jsx)(n.a,{href:"#options",children:"options"})," below."]}),"\n",(0,r.jsx)(n.p,{children:"Currently, this schematic supports the following test runners:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://jasmine.github.io/",children:(0,r.jsx)(n.strong,{children:"Jasmine"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://jestjs.io/",children:(0,r.jsx)(n.strong,{children:"Jest"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://mochajs.org/",children:(0,r.jsx)(n.strong,{children:"Mocha"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://nodejs.org/api/test.html",children:(0,r.jsx)(n.strong,{children:"Node Test Runner"})})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"With the schematics installed you can run E2E tests:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"ng e2e\n"})}),"\n",(0,r.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,r.jsx)(n.p,{children:"When adding schematics to your project you can to provide following options:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Option"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Value"}),(0,r.jsx)(n.th,{children:"Required"})]})}),(0,r.jsx)(n.tbody,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"--test-runner"})}),(0,r.jsx)(n.td,{children:"The testing framework to install along side Puppeteer."}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:'"jasmine"'}),", ",(0,r.jsx)(n.code,{children:'"jest"'}),", ",(0,r.jsx)(n.code,{children:'"mocha"'}),", ",(0,r.jsx)(n.code,{children:'"node"'})]}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"true"})})]})})]}),"\n",(0,r.jsx)(n.h2,{id:"creating-a-single-test-file",children:"Creating a single test file"}),"\n",(0,r.jsx)(n.p,{children:"Puppeteer Angular Schematic exposes a method to create a single test file."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'ng generate @puppeteer/ng-schematics:test "<TestName>"\n'})}),"\n",(0,r.jsx)(n.h3,{id:"running-test-server-and-dev-server-at-the-same-time",children:"Running test server and dev server at the same time"}),"\n",(0,r.jsxs)(n.p,{children:["By default the E2E test will run the app on the same port as ",(0,r.jsx)(n.code,{children:"ng start"}),".\nTo avoid this you can specify the port the an the ",(0,r.jsx)(n.code,{children:"angular.json"}),"\nUpdate either ",(0,r.jsx)(n.code,{children:"e2e"})," or ",(0,r.jsx)(n.code,{children:"puppeteer"})," (depending on the initial setup) to:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "e2e": {\n "builder": "@puppeteer/ng-schematics:puppeteer",\n "options": {\n "commands": [...],\n "devServerTarget": "sandbox:serve",\n "testRunner": "<TestRunner>",\n "port": 8080\n },\n ...\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Now update the E2E test file ",(0,r.jsx)(n.code,{children:"utils.ts"})," baseUrl to:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const baseUrl = 'http://localhost:8080';\n"})}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["Check out our ",(0,r.jsx)(n.a,{href:"https://pptr.dev/contributing",children:"contributing guide"})," to get an overview of what you need to develop in the Puppeteer repo."]}),"\n",(0,r.jsx)(n.h3,{id:"sandbox",children:"Sandbox"}),"\n",(0,r.jsx)(n.p,{children:"For easier development we provide a script to auto-generate the Angular project to test against. Simply run:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run sandbox -- --init\n"})}),"\n",(0,r.jsxs)(n.p,{children:["After that to run ",(0,r.jsx)(n.code,{children:"@puppeteer/ng-schematics"})," against the Sandbox Angular project run:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run sandbox\n# or to auto-build and then run schematics\nnpm run sandbox -- --build\n"})}),"\n",(0,r.jsx)(n.p,{children:"To run the creating of single test schematic:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run sandbox:test\n"})}),"\n",(0,r.jsx)(n.p,{children:"To create a multi project workspace use the following command"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run sandbox -- --init --multi\n"})}),"\n",(0,r.jsx)(n.h3,{id:"unit-testing",children:"Unit Testing"}),"\n",(0,r.jsxs)(n.p,{children:["The schematics utilize ",(0,r.jsx)(n.code,{children:"@angular-devkit/schematics/testing"})," for verifying correct file creation and ",(0,r.jsx)(n.code,{children:"package.json"})," updates. To execute the test suit:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,r.jsx)(n.h2,{id:"migrating-from-protractor",children:"Migrating from Protractor"}),"\n",(0,r.jsx)(n.h3,{id:"browser",children:"Browser"}),"\n",(0,r.jsxs)(n.p,{children:["Puppeteer has its own ",(0,r.jsx)(n.a,{href:"https://pptr.dev/api/puppeteer.browser",children:(0,r.jsx)(n.code,{children:"browser"})})," that exposes different API compared to the one exposed by Protractor."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import puppeteer from 'puppeteer';\n\n(async () => {\n const browser = await puppeteer.launch();\n\n it('should work', () => {\n const page = await browser.newPage();\n\n // Query elements\n const element = await page.$('my-component');\n\n // Do actions\n await element.click();\n });\n\n await browser.close();\n})();\n"})}),"\n",(0,r.jsx)(n.h3,{id:"query-selectors",children:"Query Selectors"}),"\n",(0,r.jsxs)(n.p,{children:["Puppeteer supports multiple types of selectors, namely, the CSS, ARIA, text, XPath and pierce selectors.\nThe following table shows Puppeteer's equivalents to ",(0,r.jsx)(n.a,{href:"https://www.protractortest.org/#/api?view=ProtractorBy",children:"Protractor By"}),"."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["For improved reliability and reduced flakiness try our\n",(0,r.jsx)(n.strong,{children:"Experimental"})," ",(0,r.jsx)(n.a,{href:"https://pptr.dev/guides/locators",children:"Locators API"})]}),"\n"]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"By"}),(0,r.jsx)(n.th,{children:"Protractor code"}),(0,r.jsx)(n.th,{children:"Puppeteer querySelector"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"CSS (Single)"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.css('<CSS>'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.$('<CSS>')"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"CSS (Multiple)"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$$(by.css('<CSS>'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.$$('<CSS>')"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Id"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.id('<ID>'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.$('#<ID>')"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"CssContainingText"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.cssContainingText('<CSS>', '<TEXT>'))"})}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"page.$('<CSS> ::-p-text(<TEXT>)')"})," `"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"DeepCss"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.deepCss('<CSS>'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.$(':scope >>> <CSS>')"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"XPath"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.xpath('<XPATH>'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.$('::-p-xpath(<XPATH>)')"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"JS"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"$(by.js('document.querySelector(\"<CSS>\")'))"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"page.evaluateHandle(() => document.querySelector('<CSS>'))"})})]})]})]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["For advanced use cases such as Protractor's ",(0,r.jsx)(n.code,{children:"by.addLocator"})," you can check Puppeteer's ",(0,r.jsx)(n.a,{href:"https://pptr.dev/guides/query-selectors#custom-selectors",children:"Custom selectors"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},75251:(e,n,t)=>{var r=t(67294),s=Symbol.for("react.element"),i=Symbol.for("react.fragment"),c=Object.prototype.hasOwnProperty,d=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function l(e,n,t){var r,i={},l=null,a=null;for(r in void 0!==t&&(l=""+t),void 0!==n.key&&(l=""+n.key),void 0!==n.ref&&(a=n.ref),n)c.call(n,r)&&!o.hasOwnProperty(r)&&(i[r]=n[r]);if(e&&e.defaultProps)for(r in n=e.defaultProps)void 0===i[r]&&(i[r]=n[r]);return{$$typeof:s,type:e,key:l,ref:a,props:i,_owner:d.current}}n.Fragment=i,n.jsx=l,n.jsxs=l},85893:(e,n,t)=>{e.exports=t(75251)},11151:(e,n,t)=>{t.d(n,{Z:()=>d,a:()=>c});var r=t(67294);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);