pages.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { Page } from 'puppeteer-core';
  2. import { constants } from './constants';
  3. import { PageObject } from './pageObjects';
  4. export interface ExpectSelectorConfig {
  5. selector: string;
  6. containsText?: string;
  7. isVisible?: boolean;
  8. }
  9. export interface TestPageType<T> {
  10. init: (page: Page) => Promise<void>;
  11. getUrl: () => Promise<string>;
  12. getUrlWithoutBaseUrl: () => Promise<string>;
  13. navigateTo: () => Promise<void>;
  14. expectSelector: (config: ExpectSelectorConfig) => Promise<void>;
  15. waitForResponse: () => Promise<void>;
  16. waitForNavigation: () => Promise<void>;
  17. waitFor: (milliseconds: number) => Promise<void>;
  18. pageObjects: PageObjects<T>;
  19. }
  20. type PageObjects<T> = { [P in keyof T]: T[P] };
  21. export interface TestPageConfig<T> {
  22. url?: string;
  23. pageObjects?: PageObjects<T>;
  24. }
  25. export class TestPage<T> implements TestPageType<T> {
  26. pageObjects: PageObjects<T> = null;
  27. private page: Page = null;
  28. private pageUrl: string = null;
  29. constructor(config: TestPageConfig<T>) {
  30. if (config.url) {
  31. this.pageUrl = `${constants.baseUrl}${config.url}`;
  32. }
  33. if (config.pageObjects) {
  34. this.pageObjects = config.pageObjects;
  35. }
  36. }
  37. init = async (page: Page): Promise<void> => {
  38. this.page = page;
  39. if (!this.pageObjects) {
  40. return;
  41. }
  42. Object.keys(this.pageObjects).forEach(key => {
  43. const pageObject: PageObject = this.pageObjects[key];
  44. pageObject.init(page);
  45. });
  46. };
  47. navigateTo = async (): Promise<void> => {
  48. this.throwIfNotInitialized();
  49. await this.page.goto(this.pageUrl);
  50. };
  51. expectSelector = async (config: ExpectSelectorConfig): Promise<void> => {
  52. this.throwIfNotInitialized();
  53. const { selector, containsText, isVisible } = config;
  54. const visible = isVisible || true;
  55. const text = containsText;
  56. const options = { visible, text } as any;
  57. await expect(this.page).toMatchElement(selector, options);
  58. };
  59. waitForResponse = async (): Promise<void> => {
  60. this.throwIfNotInitialized();
  61. await this.page.waitForResponse(response => response.url() === this.pageUrl && response.status() === 200);
  62. };
  63. waitForNavigation = async (): Promise<void> => {
  64. this.throwIfNotInitialized();
  65. await this.page.waitForNavigation();
  66. };
  67. getUrl = async (): Promise<string> => {
  68. this.throwIfNotInitialized();
  69. return await this.page.url();
  70. };
  71. getUrlWithoutBaseUrl = async (): Promise<string> => {
  72. this.throwIfNotInitialized();
  73. const url = await this.getUrl();
  74. return url.replace(constants.baseUrl, '');
  75. };
  76. waitFor = async (milliseconds: number) => {
  77. this.throwIfNotInitialized();
  78. await this.page.waitFor(milliseconds);
  79. };
  80. private throwIfNotInitialized = () => {
  81. if (!this.page) {
  82. throw new Error('pageFactory has not been initilized, did you forget to call init with a page?');
  83. }
  84. };
  85. }