AuthPage.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import { Page, Response } from '@playwright/test';
  20. import { Form } from '../components/core';
  21. import { URL } from '../utils/urls';
  22. export class AuthPage {
  23. private readonly page: Page;
  24. private readonly loginForm: Form;
  25. // Selectors specific to the auth/login page
  26. private static readonly SELECTORS = {
  27. LOGIN_FORM: '[data-test="login-form"]',
  28. USERNAME_INPUT: '[data-test="username-input"]',
  29. PASSWORD_INPUT: '[data-test="password-input"]',
  30. LOGIN_BUTTON: '[data-test="login-button"]',
  31. ERROR_SELECTORS: [
  32. '[role="alert"]',
  33. '.ant-form-item-explain-error',
  34. '.ant-form-item-explain.ant-form-item-explain-error',
  35. '.alert-danger',
  36. ],
  37. } as const;
  38. constructor(page: Page) {
  39. this.page = page;
  40. this.loginForm = new Form(page, AuthPage.SELECTORS.LOGIN_FORM);
  41. }
  42. /**
  43. * Navigate to the login page
  44. */
  45. async goto(): Promise<void> {
  46. await this.page.goto(URL.LOGIN);
  47. }
  48. /**
  49. * Wait for login form to be visible
  50. */
  51. async waitForLoginForm(): Promise<void> {
  52. await this.loginForm.waitForVisible({ timeout: 5000 });
  53. }
  54. /**
  55. * Login with provided credentials
  56. * @param username - Username to enter
  57. * @param password - Password to enter
  58. */
  59. async loginWithCredentials(
  60. username: string,
  61. password: string,
  62. ): Promise<void> {
  63. const usernameInput = this.loginForm.getInput(
  64. AuthPage.SELECTORS.USERNAME_INPUT,
  65. );
  66. const passwordInput = this.loginForm.getInput(
  67. AuthPage.SELECTORS.PASSWORD_INPUT,
  68. );
  69. const loginButton = this.loginForm.getButton(
  70. AuthPage.SELECTORS.LOGIN_BUTTON,
  71. );
  72. await usernameInput.fill(username);
  73. await passwordInput.fill(password);
  74. await loginButton.click();
  75. }
  76. /**
  77. * Get current page URL
  78. */
  79. async getCurrentUrl(): Promise<string> {
  80. return this.page.url();
  81. }
  82. /**
  83. * Get the session cookie specifically
  84. */
  85. async getSessionCookie(): Promise<{ name: string; value: string } | null> {
  86. const cookies = await this.page.context().cookies();
  87. return cookies.find((c: any) => c.name === 'session') || null;
  88. }
  89. /**
  90. * Check if login form has validation errors
  91. */
  92. async hasLoginError(): Promise<boolean> {
  93. const visibilityPromises = AuthPage.SELECTORS.ERROR_SELECTORS.map(
  94. selector => this.page.locator(selector).isVisible(),
  95. );
  96. const visibilityResults = await Promise.all(visibilityPromises);
  97. return visibilityResults.some((isVisible: any) => isVisible);
  98. }
  99. /**
  100. * Wait for a login request to be made and return the response
  101. */
  102. async waitForLoginRequest(): Promise<Response> {
  103. return this.page.waitForResponse(
  104. (response: any) =>
  105. response.url().includes('/login/') &&
  106. response.request().method() === 'POST',
  107. );
  108. }
  109. }