pages.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. // @ts-ignore
  44. const pageObject: PageObject = this.pageObjects[key];
  45. pageObject.init(page);
  46. });
  47. };
  48. navigateTo = async (): Promise<void> => {
  49. this.throwIfNotInitialized();
  50. console.log('Trying to navigate to:', this.pageUrl);
  51. await this.page.goto(this.pageUrl);
  52. };
  53. expectSelector = async (config: ExpectSelectorConfig): Promise<void> => {
  54. this.throwIfNotInitialized();
  55. const { selector, containsText, isVisible } = config;
  56. const visible = isVisible || true;
  57. const text = containsText;
  58. const options = { visible, text } as any;
  59. await expect(this.page).toMatchElement(selector, options);
  60. };
  61. waitForResponse = async (): Promise<void> => {
  62. this.throwIfNotInitialized();
  63. await this.page.waitForResponse(response => response.url() === this.pageUrl && response.status() === 200);
  64. };
  65. waitForNavigation = async (): Promise<void> => {
  66. this.throwIfNotInitialized();
  67. await this.page.waitForNavigation();
  68. };
  69. getUrl = async (): Promise<string> => {
  70. this.throwIfNotInitialized();
  71. return await this.page.url();
  72. };
  73. getUrlWithoutBaseUrl = async (): Promise<string> => {
  74. this.throwIfNotInitialized();
  75. const url = await this.getUrl();
  76. return url.replace(constants.baseUrl, '');
  77. };
  78. waitFor = async (milliseconds: number) => {
  79. this.throwIfNotInitialized();
  80. await this.page.waitFor(milliseconds);
  81. };
  82. private throwIfNotInitialized = () => {
  83. if (!this.page) {
  84. throw new Error('pageFactory has not been initilized, did you forget to call init with a page?');
  85. }
  86. };
  87. }