Просмотр исходного кода

Merge pull request #8911 from weseek/support/148552-replace-tests-with-playwright

support: Replace tests with Playwright (22-sharelink/22-sharelink--access-to-sharelink)
Shun Miyazawa 1 год назад
Родитель
Сommit
45870d123a

+ 1 - 1
.github/workflows/reusable-app-prod.yml

@@ -213,7 +213,7 @@ jobs:
       fail-fast: false
       matrix:
         # List string expressions that is comma separated ids of tests in "test/cypress/integration"
-        spec-group: ['20', '21', '22', '23', '30', '50']
+        spec-group: ['20', '21', '23', '30', '50']
 
     services:
       mongodb:

+ 37 - 0
apps/app/playwright/22-sharelink/access-to-sharelink.spec.ts

@@ -0,0 +1,37 @@
+import { test, expect } from '@playwright/test';
+
+import { login } from '../utils/Login';
+
+test.describe.serial('Access to sharelink by guest', () => {
+  let createdSharelink: string | null;
+
+  test('Prepare sharelink', async({ page }) => {
+    await page.goto('/Sandbox/Bootstrap5');
+
+    // Create Sharelink
+    await page.getByTestId('open-page-item-control-btn').click();
+    await page.getByTestId('open-page-accessories-modal-btn-with-share-link-management-data-tab').click();
+    await page.getByTestId('btn-sharelink-toggleform').click();
+    await page.getByTestId('btn-sharelink-issue').click();
+
+    // Get ShareLink
+    createdSharelink = await page.getByTestId('share-link').textContent();
+    expect(createdSharelink).toHaveLength(24);
+  });
+
+  test('The sharelink page is successfully loaded', async({ page }) => {
+    await page.goto('/');
+
+    // Logout
+    await page.getByTestId('personal-dropdown-button').click();
+    await expect(page.getByTestId('logout-button')).toBeVisible();
+    await page.getByTestId('logout-button').click();
+    await page.waitForURL('http://localhost:3000/login');
+
+    // Access sharelink
+    await page.goto(`/share/${createdSharelink}`);
+    await expect(page.locator('.page-meta')).toBeVisible();
+
+    await login(page);
+  });
+});

+ 5 - 20
apps/app/playwright/auth.setup.ts

@@ -1,24 +1,9 @@
-import path from 'node:path';
+import { test as setup } from '@playwright/test';
 
-import { test as setup, expect } from '@playwright/test';
-
-const authFile = path.resolve(__dirname, './.auth/admin.json');
+import { login } from './utils/Login';
 
+// Commonised login process for use elsewhere
+// see: https://github.com/microsoft/playwright/issues/22114
 setup('Authenticate as the "admin" user', async({ page }) => {
-  // Perform authentication steps. Replace these actions with your own.
-  await page.goto('/admin');
-
-  const loginForm = await page.$('form#login-form');
-
-  if (loginForm != null) {
-    await page.getByLabel('Username or E-mail').fill('admin');
-    await page.getByLabel('Password').fill('adminadmin');
-    await page.locator('[type=submit]').filter({ hasText: 'Login' }).click();
-  }
-
-  await page.waitForURL('/admin');
-  await expect(page).toHaveTitle(/Wiki Management Homepage/);
-
-  // End of authentication steps.
-  await page.context().storageState({ path: authFile });
+  await login(page);
 });

+ 24 - 0
apps/app/playwright/utils/Login.ts

@@ -0,0 +1,24 @@
+import path from 'node:path';
+
+import { expect, type Page } from '@playwright/test';
+
+const authFile = path.resolve(__dirname, '../.auth/admin.json');
+
+export const login = async(page: Page): Promise<void> => {
+  // Perform authentication steps. Replace these actions with your own.
+  await page.goto('/admin');
+
+  const loginForm = await page.$('form#login-form');
+
+  if (loginForm != null) {
+    await page.getByLabel('Username or E-mail').fill('admin');
+    await page.getByLabel('Password').fill('adminadmin');
+    await page.locator('[type=submit]').filter({ hasText: 'Login' }).click();
+  }
+
+  await page.waitForURL('/admin');
+  await expect(page).toHaveTitle(/Wiki Management Homepage/);
+
+  // End of authentication steps.
+  await page.context().storageState({ path: authFile });
+};

+ 1 - 0
apps/app/playwright/utils/index.ts

@@ -1 +1,2 @@
 export * from './CollapseSidebar';
+export * from './Login';

+ 1 - 1
apps/app/src/components/PageAccessoriesModal/ShareLink/ShareLinkList.tsx

@@ -25,7 +25,7 @@ const ShareLinkTr = (props: ShareLinkTrProps): JSX.Element => {
   return (
     <tr key={shareLinkId}>
       <td className="d-flex justify-content-between align-items-center">
-        <span>{shareLinkId}</span>
+        <span data-testid="share-link">{shareLinkId}</span>
 
         { isRelatedPageExists && (
           <CopyDropdown

+ 1 - 1
apps/app/src/components/Sidebar/SidebarNav/PersonalDropdown.tsx

@@ -108,7 +108,7 @@ export const PersonalDropdown = (): JSX.Element => {
             </span>
           </DropdownItem>
 
-          <DropdownItem onClick={logoutHandler} className={`my-1 ${styles['personal-dropdown-item']}`}>
+          <DropdownItem data-testid="logout-button" onClick={logoutHandler} className={`my-1 ${styles['personal-dropdown-item']}`}>
             <span className="d-flex align-items-center">
               <span className="item-icon material-symbols-outlined me-2 pb-0 fs-6">logout</span>
               <span className="item-text">{t('Sign out')}</span>

+ 0 - 71
apps/app/test/cypress/e2e/22-sharelink/22-sharelink--access-to-sharelink.cy.ts

@@ -1,71 +0,0 @@
-context('Access to sharelink by guest', () => {
-  const ssPrefix = 'access-to-sharelink-by-guest-';
-
-  let createdSharelinkId: string;
-
-  it('Prepare sharelink', () => {
-    // login
-    cy.fixture("user-admin.json").then(user => {
-      cy.login(user.username, user.password);
-    });
-
-    cy.visit('/Sandbox/Bootstrap5');
-
-    // open dropdown
-    cy.waitUntil(() => {
-      // do
-      cy.getByTestid('grw-contextual-sub-nav').within(() => {
-        cy.getByTestid('open-page-item-control-btn', { timeout: 14000 }).find('button').click({force: true});
-      });
-      // wait until
-      return cy.getByTestid('page-item-control-menu').then($elem => $elem.is(':visible'))
-    });
-
-    // open modal
-    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
-      cy.getByTestid('open-page-accessories-modal-btn-with-share-link-management-data-tab').click({force: true});
-    });
-    cy.waitUntilSpinnerDisappear();
-    cy.getByTestid('page-accessories-modal').should('be.visible');
-    cy.getByTestid('share-link-management').should('be.visible');
-
-    // create share link
-    cy.getByTestid('share-link-management').within(() => {
-      // open form
-      cy.waitUntil(() => {
-        // do
-        cy.getByTestid('btn-sharelink-toggleform').click();
-        // wait until
-        return cy.getByTestid('btn-sharelink-issue').then($elem => $elem.is(':visible'))
-      });
-
-      cy.getByTestid('btn-sharelink-issue').should('be.visible').click();
-
-      cy.get('tbody')
-        .find('tr').first() // the first row
-        .find('td').first() // the first column
-        .find('span').first().then((elem) => {
-
-        // store id
-        createdSharelinkId = elem.text();
-        // overwrite the label
-        elem.html('63d100000000000000000000');
-      });
-    });
-
-    cy.getByTestid('page-accessories-modal').within(() => { cy.screenshot(`${ssPrefix}-sharelink-created`) });
-  });
-
-  it('The sharelink page is successfully loaded', () => {
-    cy.visit(`/share/${createdSharelinkId}`);
-
-    cy.getByTestid('grw-contextual-sub-nav').should('be.visible');
-    cy.get('.wiki').should('be.visible');
-
-    cy.waitUntilSkeletonDisappear();
-    cy.screenshot(`${ssPrefix}-access-to-sharelink`);
-  });
-
-});
-
-