{"_id":"@autometa/page-components","_rev":"4-6173a3e167be23b8fcf675b1bb4eac67","name":"@autometa/page-components","dist-tags":{"latest":"0.0.3"},"versions":{"0.0.0":{"name":"@autometa/page-components","version":"0.0.0","license":"MIT","repository":{"type":"git","url":"git+https://github.com/Bendat/autometa.git"},"homepage":"https://bendat.github.io/autometa/docs/ui-testing/selenium/page-component-model/intro","keywords":["page object","page object model","selenium","automation","page components model"],"dependencies":{"reflect-metadata":"^0.1.13","tsyringe":"^4.7.0"},"devDependencies":{"@types/selenium-webdriver":"^4.1.5","colors-cli":"^1.0.28","selenium-webdriver":"^4.4.0","tslib":"^2.4.0"},"main":"./src/index.js","typings":"./src/index.d.ts","gitHead":"bc20d4b522155d4807eb0e34b7c4f7df304d72ad","description":"This library was generated with [Nx](https://nx.dev).","bugs":{"url":"https://github.com/Bendat/autometa/issues"},"_id":"@autometa/page-components@0.0.0","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-1g/lzr4Oj+r0IXfO1H/b27xXbIpjEu8Rh0QCbIVl+Z6HHkAxJJy0gD7VSW4ygahARtd8POVxEkk5x0RH2gMt2A==","shasum":"195ab1cf24549b197888fbdb9f002a0d7ebf2cd8","tarball":"https://registry.npmjs.org/@autometa/page-components/-/page-components-0.0.0.tgz","fileCount":140,"unpackedSize":182563,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC1KAxjqhGh8dBsEYzzXZW4RK/Gy8yHTnw52j7cdcFVhwIhAIYJU4puZmhf7OD6wCbTTFAY8RhNr/OJ3ToSqxrJ/kUu"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjJ4RHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoa5g//bQk+yO/jbIU3wPiNUTCy7i1WxS4fMe3t0+0vOWJH5QwhWU+o\r\nKqkJ9WgdyhrTv5DrVVJSf2I4eOvwjxBFy7Shq3GmPUSb3fm2uBd/DaoNg7Yf\r\nL6GLXXbPHAIMxRBla/YjcycVz/6SrMFPonQ3FdVc2XAEBJ8xjqX2bK81Bkz1\r\n4wpKVb/nXxldrXUbkIUf5zTiHtf7Hj47uJt6vs5S1SCCA/iGSJ3kWKG9kHW0\r\nF+zPooeNfZjjJ60A4vQCrAVr1K9U/yGxVIHPHOn1nFYpctCPQuieD+MEMxtI\r\nBdQZ1OFDMUE53eeP3zZ2HUggAcAMoOan57sCYFOruPcxYkeA4lQche8imu1R\r\nZiRbIvNPIoP6TLzb7YW8IQkZpJ2K4Pzxo4F5hf97QcVQJrKEQ1r7p96y6exQ\r\n3YERyiQO4OFUoxUXViJsXMPovFX837xI0XDMA0KkXHQAvYGL3INstkGjz2J4\r\nOHYlCdbfXymKLTxbzPDxA2UHRqH3AuUzGxbkswCet9DKhgBrMnbzuALT4cBF\r\nKk8dYpGzuuR75621VD0X0CAsl0OZulrzWXcLM1PHb3j+Mdo80EKcyEL4qfLt\r\nMGPQHVy0vi++msMTeUfcmfFntCpz+bYSx8NJnKg3szU0BdFoOVAvYaL7/nSo\r\nD68Bdo3AiuM4yvzMDiAf75gg6lYLPJZRS58=\r\n=n1M/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"benah","email":"benaherne@outlook.ie"},"directories":{},"maintainers":[{"name":"benah","email":"benaherne@outlook.ie"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/page-components_0.0.0_1663534150922_0.2073151211808304"},"_hasShrinkwrap":false},"0.0.1":{"name":"@autometa/page-components","version":"0.0.1","license":"MIT","repository":{"type":"git","url":"git+https://github.com/Bendat/autometa.git"},"homepage":"https://bendat.github.io/autometa/docs/ui-testing/selenium/page-component-model/intro","keywords":["page object","page object model","selenium","automation","page components model"],"dependencies":{"reflect-metadata":"^0.1.13","tsyringe":"^4.7.0","colors-cli":"^1.0.28"},"devDependencies":{"@types/jest":"^29.0.2","@types/selenium-webdriver":"^4.1.5","selenium-webdriver":"^4.4.0","tslib":"^2.4.0"},"main":"./src/index.js","typings":"./src/index.d.ts","gitHead":"bc20d4b522155d4807eb0e34b7c4f7df304d72ad","description":"**Autometa** Page Components Model is an (early and experimental) interpretation of the Page Object Model, built for use with selenium","bugs":{"url":"https://github.com/Bendat/autometa/issues"},"_id":"@autometa/page-components@0.0.1","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-dtNK3CjsJytO/u8mWG394ZbJSt7uEf7NIxt/d04AlMUSBmBzL6PKwGbRhiMAAFaOd6yGccEHK6JaOiawrQ+Idw==","shasum":"0555044972b57fb083941f4cf5525cd99826147e","tarball":"https://registry.npmjs.org/@autometa/page-components/-/page-components-0.0.1.tgz","fileCount":143,"unpackedSize":190446,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID3jT24u/WA+bubFieY72LzD3E86kbxLBQ38ovFOTYiDAiEApjtiSCuZmqyaAzUl9SfOXV2CsTAGM0MPV5TIOUMOgoA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjJ4SwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrhdg//cnSY9HniPIwqO/GAyx01Wt024ZZ6Ync87Xfqq41aA6Qr4r9M\r\n/zZHyS8+YzMfg9XuHgAM6vG8aslQNap+2i50I6VF9tkxDX2oRuY0rxC/w4if\r\ne+uRSDu4CD98Yr2l/9AoHpATsCIt3fpLuFEa24EILTlR7+krCLtoYWKldqG4\r\nt3ajWXGEYhfj+qRYvWS1Aq/5Mzry/46e3yA2dMjAo/ZsMOI+ljHbQcDG13xF\r\nJ6q0oSaZjFR7dFf5MDtXGXgysJTIUNBDxfxxouCEKfwEzfJtCB6tsZS7t1zh\r\nMn2r2oFbVp73MQatCgKWTa8jxNChuBI2D3F2Oy19wVFgRtYvYOr7GqGyT3sC\r\nvx6k/m+8bQsGz1susaA3Z4R9oWMAhJAjEJzw6PgYn0iOC3zEv49k8QnPWIY0\r\nSxqHDxO5C235aUUIEpDMZibR9gS3ME93C/Q6CM788b/kEUI7fmSphEiRprC9\r\nn0NgjIgks4JX4385hmbipx3SLuHS9LSOgofK+G1jrsS9txcEIl4L4DjS96XH\r\nN44tHoMDSAIyG/lANfWACt5sdmHE+5VYznUdTytZ3jrHOcCD5DxUwlaALqYn\r\ntyBlzEggmapEHeGGaOPOy5sIqTv+NIV4nw3PnG0dCRBtsOO1CTq8jNUFxqFi\r\n8bUGqxlKUu1q8k3pOxHNKsfmeGL0uw1+8mM=\r\n=e+CP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"benah","email":"benaherne@outlook.ie"},"directories":{},"maintainers":[{"name":"benah","email":"benaherne@outlook.ie"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/page-components_0.0.1_1663534256701_0.48499554399254996"},"_hasShrinkwrap":false},"0.0.3":{"name":"@autometa/page-components","version":"0.0.3","license":"MIT","repository":{"type":"git","url":"git+https://github.com/Bendat/autometa.git"},"homepage":"https://bendat.github.io/autometa/docs/ui-testing/selenium/page-component-model/intro","keywords":["page object","page object model","selenium","automation","page components model"],"dependencies":{"reflect-metadata":"^0.1.13","tsyringe":"^4.7.0","colors-cli":"^1.0.28"},"devDependencies":{"@types/jest":"^29.0.2","@types/selenium-webdriver":"^4.1.5","selenium-webdriver":"^4.4.0","tslib":"^2.4.0"},"main":"./src/index.js","typings":"./src/index.d.ts","gitHead":"09d816c5c9f8f19bdd00b3d2326a5046fa5d2dd6","description":"**Autometa** Page Components Model is an (early and experimental) interpretation of the Page Object Model, built for use with selenium","bugs":{"url":"https://github.com/Bendat/autometa/issues"},"_id":"@autometa/page-components@0.0.3","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-8voXZ2VoXAv99UccN3zIvspt1n+bQb6rlgYaZg87qS+72HnmeNj9G8ME1Zf8HNhYB9MBvSzLWHJoJCK7V667wg==","shasum":"c18439a1e378fd016a42c88de2cfa3507ba6af90","tarball":"https://registry.npmjs.org/@autometa/page-components/-/page-components-0.0.3.tgz","fileCount":143,"unpackedSize":191004,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE7La7dfb1/6kUBbsCbLdDZR1Js0aT4ffgkBADfZYCidAiEAwcBRTy2gGDYdMiEmgoq1Tfun1hFwGY0ONPbQSzL7w6c="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKLBqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqUfg//frYqioZLthIrFn8Ohp2lHXbZCeYJX8acZR+/R5r8WVRUGYU0\r\nrWZT+6/RbFojM+ZzAvZOWf1Tb6i2FjGnmfQYeIb6byflmOa+Lj9V6epEIHT5\r\ng6xamLsHluluj7N6rQVBt0ZKIQ9nBs6DK/XqYIg/Wof8odlgvDhFZk3tBIBh\r\n3KubnwXj4vaSlaUdv2ejQvy4v85MXkXn6IisZ3bggMsbgXiRqhPvbbuK+Iu+\r\nJjPFmfUZWrZEML5gUUp7zxvzIEsvUjGiFI7ARdFFRoFHCcN4EnQ3MFucZ1Sb\r\nXRnbHMZEdZADsGgQ4QJJC2kqBpUO460Y6Llx+Nwaoc2Er/Dd+gEFfMNCBQVW\r\nOzQNApgEF0imsRgJsK99ZWz2wswiphDWz1JQCiHGUJHb7rKxd6F8moY5pV9R\r\nVOtj+JCvnJdN+Egvmmnjh+fSmF/lt9TcK63oAxf7p+Hplh1+QDPcTfV7MtWu\r\nMuOkm7eoPr1snuU3NHSEYvDu6IWCM2UD0eREptYD5Gst8FHxumBvtlrKsi2Y\r\n/ni3eEbOiFi/oXFdYdZafUy9NuSWO4K28I0yYdegggewD/UJACY0jupOb2QX\r\nyFJPDjTL8vPdGgzWC6dN/2/+8MQHDvoFcy9tR+LZflNfmB0UUxa4jY3y6M/I\r\nG63CIIoOaZbhyzMZbEGoXikP/WrA8/GJ7X0=\r\n=6egH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"benah","email":"benaherne@outlook.ie"},"directories":{},"maintainers":[{"name":"benah","email":"benaherne@outlook.ie"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/page-components_0.0.3_1663610985887_0.0759738208707017"},"_hasShrinkwrap":false}},"time":{"created":"2022-09-18T20:49:10.807Z","0.0.0":"2022-09-18T20:49:11.113Z","modified":"2022-09-19T18:09:46.198Z","0.0.1":"2022-09-18T20:50:56.875Z","0.0.2":"2022-09-18T20:56:14.665Z","0.0.3":"2022-09-19T18:09:46.125Z"},"maintainers":[{"name":"benah","email":"benaherne@outlook.ie"}],"description":"**Autometa** Page Components Model is an (early and experimental) interpretation of the Page Object Model, built for use with selenium","homepage":"https://bendat.github.io/autometa/docs/ui-testing/selenium/page-component-model/intro","keywords":["page object","page object model","selenium","automation","page components model"],"repository":{"type":"git","url":"git+https://github.com/Bendat/autometa.git"},"bugs":{"url":"https://github.com/Bendat/autometa/issues"},"license":"MIT","readme":"# Page Components Model\r\n\r\n### [Full Documentation/Tutorial Here](https://bendat.github.io/autometa/docs/ui-testing/selenium/page-component-model/intro)\r\n\r\n**Autometa** Page Components Model is an (early and experimental) interpretation of the Page Object Model, built for use with selenium\r\n\r\n## Quick Intro\r\n\r\nBuild Page Objects in a declarative manner, without instantiation or\r\nwiring logic, and no explicit waiting in tests:\r\n\r\n```ts\r\nexport class MyHomePage extends WebPage {\r\n  @component(By.className('login-btn'))\r\n  login: Button;\r\n}\r\n```\r\n\r\nAnd that's enough to start testing:\r\n\r\n```ts title='Using Jest'\r\nconst url = process.env.MY_URL;\r\nconst builder = new Builder().forBrowser(Browser.CHROME);\r\nconst site = Site(url, builder);\r\n\r\ndescribe('Clicking the login button', () => {\r\n  let page: MyHomePage;\r\n  beforeEach(async () => {\r\n    page = await site.browse(MyHomePage);\r\n  });\r\n\r\n  it('should wait for the page to load and click the login button', () => {\r\n    await page.waitForTitleIs('My Home Page!');\r\n    await page.login.click();\r\n  });\r\n});\r\n```\r\n\r\nEasily create new components to better describe the intent of your\r\nPage Objects\r\n\r\n```ts\r\nexport class MyLoginModal extends Component {\r\n  @component(By.css('input[type=\"username\"'))\r\n  username: TextInput;\r\n  @component(By.css('input[type=\"password\"'))\r\n  password: TextInput;\r\n  // Automatically scoped to this modal. No conflict with\r\n  // the '.login-btn' button in the parent DOM\r\n  @component(By.className('login-btn'))\r\n  login: Button;\r\n}\r\n```\r\n\r\nNow start composing behavior\r\n\r\n```ts title='my-login-modal.ts'\r\nexport class MyLoginModal extends Component {\r\n  @component(By.css('input[type=\"username\"'))\r\n  username: TextInput;\r\n\r\n  @component(By.css('input[type=\"password\"'))\r\n  password: TextInput;\r\n\r\n  // Automatically scoped to this modal. No conflict with\r\n  // the '.login-btn' button in the parent DOM.\r\n  // Set wait-until condition and max timeout for slower items\r\n  @component(By.className('login-btn'), Until.isDisplayed, 3500)\r\n  login: Button;\r\n\r\n  logUserIn = async (username: string, password: string) => {\r\n    await this.username.write(username);\r\n    await this.password.write(password);\r\n    await login.click();\r\n  };\r\n}\r\n```\r\n\r\nAnd make a shortcut on our home-page if we like\r\n\r\n```ts title='my-home-page.ts'\r\nexport class MyLoginModal extends Component {\r\n  @component(By.id('login-modal'))\r\n  loginModal: MyLoginModal;\r\n\r\n  @component(By.className('login-btn'))\r\n  login: Button;\r\n\r\n  logUserIn = async (username: string, password: string) => {\r\n    await login.click();\r\n    await this.loginModal.logUserIn(username, password);\r\n  };\r\n}\r\n```\r\n\r\nAnd begin using it in tests\r\n\r\n```ts title='Using Jest'\r\nconst url = process.env.MY_URL;\r\nconst builder = new Builder().forBrowser(Browser.CHROME);\r\nconst site = Site(url, builder);\r\n\r\ndescribe('Logging the user in', () => {\r\n  let page: MyHomePage;\r\n  beforeEach(async () => {\r\n    page = await site.browse(MyHomePage);\r\n  });\r\n\r\n  it('should log the user in', () => {\r\n    await page.waitForTitleIs('My Home Page!');\r\n    await page.logUserIn('myname', 'mYpa55');\r\n    await page.waitForTitleIs('mynames Profile')\r\n  });\r\n});\r\n```\r\n\r\nOther pages can also be bound for easy navigation\r\n\r\n```ts\r\nexport class MyHomePage extends WebPage{\r\n    @page()\r\n    myProfilePage: MyProfilePage\r\n}\r\n```\r\n\r\n## Benefits\r\n\r\n### Declarative Model\r\n\r\nSpend less time assembling Page Models. Declare models quickly\r\nand focus on writing tests.\r\n\r\n### Scoped Element Searches\r\n\r\nComponents automatically use their parents `WebElement` to initialize,\r\nand only use the `WebDriver` if the parent Page Object is a WebPage.\r\n\r\n### Lazy Initialization\r\n\r\nComponents initialize early so `WebElement`s don't have to. WebElements are handled lazily, loaded only when acted upon,\r\nimproving start up performance for element-based Page Object Models\r\n\r\n### Automatic Waiting\r\n\r\nLazily loaded elements when activated will automatically be waited\r\nfor fluently. `Until` strategy can be configured multiple ways.\r\n\r\n### Automatic Staleness Handling\r\n\r\nElements will detect when they're stale and propagate a refresh\r\nrequest up the Page Model, forcing affected Components to lazily reload when next accessed instead of crashing.\r\n\r\n### Automatic Logging\r\n\r\n(WIP) - only supports `node` `console` at this time.\r\n\r\nEvery interaction with the WebDriver is logged in detail with 'breadcrumbs' describing\r\nexactly what's happening in the tests\r\n\r\nExample log:\r\n\r\n```\r\n  console.info\r\n    Clicking On IndexPage[$root] >\r\n      GridContainer[grid, By(css selector, .grid)] > \r\n        SimpleTypeDiv[simpleTypes, By(css selector, div:nth-of-type(1))] >\r\n          Button[button, By(css selector, button)]( { text: \"Click Me\" } )\r\n\r\n      at Button.#logActionOccurring (src/lib/meta-types/component.ts:558:17)\r\n\r\n  console.info\r\n    Searching for [ListItem, By(css selector, li)] in IndexPage[$root] > \r\n      GridContainer[grid, By(css selector, .grid)] >\r\n        SimpleTypeDiv[simpleTypes, By(css selector, div:nth-of-type(1))] >\r\n          UnorderedList[unorderedList, By(css selector, ul)]\r\n\r\n      at ElementArray.<anonymous> (src/lib/meta-types/component.ts:540:17)\r\n```\r\n\r\n## Easily Handle Collections of Similar Models\r\n\r\nPatterns provided for handling dynamic or indeterminate content which share a model or structure.\r\n\r\nExample html:\r\n\r\n```html\r\n<ol>\r\n  <li>first</li>\r\n  <li>second</li>\r\n  <li>third</li>\r\n  <li>fourth</li>\r\n</ol>\r\n```\r\n\r\nExample Page Model:\r\n\r\n```ts\r\nexport class MyPageWithList extends WebPage {\r\n  @collection(By.css('ol'), ListItem, By.css('li'))\r\n  numericList: Collection<ListItem>;\r\n}\r\n```\r\n\r\nExample test:\r\n\r\n```ts\r\nit('should check the list', () => {\r\n  // array-like functions\r\n  const expected = ['first', 'second', 'third', 'fourth'];\r\n\r\n  await page.numericList.forEach(async (li, idx) => {\r\n    expect(await li.text).toBe(expected[idx]);\r\n  });\r\n\r\n  const mapped = await page.numericList.map(async (li) => li.text);\r\n  expect(mapped).toStrictEqual(expected);\r\n\r\n  expect(await page.numericList.at(0)).toBe(expected[0]);\r\n\r\n  // works with for...of\r\n  for (const li of await page.numericList.values) {\r\n    expect(await li.text).toBe(expected.shift());\r\n  }\r\n});\r\n```\r\n","readmeFilename":"README.md"}