Kaynağa Gözat

Merge branch 'feat/119760' of https://github.com/weseek/growi into feat/119760

Shun Miyazawa 2 yıl önce
ebeveyn
işleme
3b8ed4c2be
27 değiştirilmiş dosya ile 361 ekleme ve 185 silme
  1. 2 2
      .github/workflows/reusable-app-prod.yml
  2. 1 0
      apps/app/config/ci/.env.local.for-ci
  3. 1 1
      apps/app/cypress.config.ts
  4. 1 0
      apps/app/src/components/PageDuplicateModal.tsx
  5. 1 1
      apps/app/src/components/SavePageControls/GrantSelector.tsx
  6. 0 0
      apps/app/test/cypress/e2e/0-advanced-examples/misc.cy.ts
  7. 0 0
      apps/app/test/cypress/e2e/0-advanced-examples/viewport.cy.ts
  8. 0 0
      apps/app/test/cypress/e2e/10-install/10-install--install.cy.ts
  9. 0 0
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--access-to-page.cy.ts
  10. 0 0
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--access-to-pagelist.cy.ts
  11. 0 0
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--click-page-icons.cy.ts
  12. 0 0
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--sticky-features.cy.ts
  13. 0 181
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--use-tools.cy.ts
  14. 0 0
      apps/app/test/cypress/e2e/20-basic-features/20-basic-features--username-mention.cy.ts
  15. 0 0
      apps/app/test/cypress/e2e/21-basic-features-for-guest/21-basic-features-for-guest--access-to-page.cy.ts
  16. 0 0
      apps/app/test/cypress/e2e/21-basic-features-for-guest/21-basic-features-for-guest--sticky-for-guest.cy.ts
  17. 0 0
      apps/app/test/cypress/e2e/22-sharelink/22-sharelink--access-to-sharelink.cy.ts
  18. 194 0
      apps/app/test/cypress/e2e/23-editor/23-editor--saving.cy.ts
  19. 153 0
      apps/app/test/cypress/e2e/23-editor/23-editor--with-navigation.cy.ts
  20. 1 0
      apps/app/test/cypress/e2e/23-editor/assets/example.txt
  21. 0 0
      apps/app/test/cypress/e2e/30-search/30-search--search.cy.ts
  22. 0 0
      apps/app/test/cypress/e2e/40-admin/40-admin--access-to-admin-page.cy.ts
  23. 0 0
      apps/app/test/cypress/e2e/50-sidebar/50-sidebar--access-to-side-bar.cy.ts
  24. 0 0
      apps/app/test/cypress/e2e/50-sidebar/50-sidebar--switching-sidebar-mode.cy.ts
  25. 0 0
      apps/app/test/cypress/e2e/60-home/60-home--home.cy.ts
  26. 2 0
      package.json
  27. 5 0
      yarn.lock

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

@@ -217,7 +217,7 @@ jobs:
       fail-fast: false
       matrix:
         # List string expressions that is comma separated ids of tests in "test/cypress/integration"
-        spec-group: ['10', '20', '21', '22', '30', '40', '50', '60']
+        spec-group: ['10', '20', '21', '22', '23', '30', '40', '50', '60']
 
     services:
       mongodb:
@@ -289,7 +289,7 @@ jobs:
     - name: Determine spec expression
       id: determine-spec-exp
       run: |
-        SPEC=`node bin/github-actions/generate-cypress-spec-arg.mjs --prefix="test/cypress/integration/" --suffix="-*/**" "${{ matrix.spec-group }}"`
+        SPEC=`node bin/github-actions/generate-cypress-spec-arg.mjs --prefix="test/cypress/e2e/" --suffix="-*/*.cy.{ts,tsx}" "${{ matrix.spec-group }}"`
         echo "value=$SPEC" >> $GITHUB_OUTPUT
 
     - name: Copy dotenv file for ci

+ 1 - 0
apps/app/config/ci/.env.local.for-ci

@@ -1 +1,2 @@
 FORMAT_NODE_LOG=true
+FILE_UPLOAD=mongodb

+ 1 - 1
apps/app/cypress.config.ts

@@ -3,7 +3,7 @@ import { defineConfig } from 'cypress';
 export default defineConfig({
   e2e: {
     baseUrl: 'http://localhost:3000',
-    specPattern: 'test/cypress/integration/',
+    specPattern: 'test/cypress/e2e/**/*.cy.{ts,tsx}',
     supportFile: 'test/cypress/support/index.ts',
     setupNodeEvents: (on) => {
       // change screen size

+ 1 - 0
apps/app/src/components/PageDuplicateModal.tsx

@@ -252,6 +252,7 @@ const PageDuplicateModal = (): JSX.Element => {
         <button
           type="button"
           className="btn btn-primary"
+          data-testid="btn-duplicate"
           onClick={duplicate}
           disabled={!submitButtonEnabled}
         >

+ 1 - 1
apps/app/src/components/SavePageControls/GrantSelector.tsx

@@ -137,7 +137,7 @@ const GrantSelector = (props: Props): JSX.Element => {
     }
 
     return (
-      <div className="form-group grw-grant-selector mb-0">
+      <div className="form-group grw-grant-selector mb-0" data-testid="grw-grant-selector">
         <UncontrolledDropdown direction="up">
           <DropdownToggle color={dropdownToggleBtnColor} caret className="d-flex justify-content-between align-items-center" disabled={disabled}>
             {dropdownToggleLabelElm}

+ 0 - 0
apps/app/test/cypress/integration/0-advanced-examples/misc.spec.ts → apps/app/test/cypress/e2e/0-advanced-examples/misc.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/0-advanced-examples/viewport.spec.ts → apps/app/test/cypress/e2e/0-advanced-examples/viewport.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/10-install/10-install--install.spec.ts → apps/app/test/cypress/e2e/10-install/10-install--install.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-page.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--access-to-page.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-pagelist.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--access-to-pagelist.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/20-basic-features/20-basic-features--click-page-icons.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--click-page-icons.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/20-basic-features/20-basic-features--sticky-features.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--sticky-features.cy.ts


+ 0 - 181
apps/app/test/cypress/integration/20-basic-features/20-basic-features--use-tools.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--use-tools.cy.ts

@@ -9,130 +9,6 @@ context('Modal for page operation', () => {
     });
   });
 
-  it("PageCreateModal is shown and closed successfully", () => {
-    cy.visit('/');
-
-    cy.waitUntil(() => {
-      // do
-      cy.getByTestid('newPageBtn').click({force: true});
-      // wait until
-      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
-    });
-
-    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.screenshot(`${ssPrefix}new-page-modal-opened`);
-      cy.get('button.close').click();
-    });
-
-    cy.collapseSidebar(true, true);
-    cy.screenshot(`${ssPrefix}page-create-modal-closed`);
-  });
-
-  it("Successfully Create Today's page", () => {
-    const pageName = "Today's page";
-    cy.visit('/');
-
-    cy.waitUntil(() => {
-      // do
-      cy.getByTestid('newPageBtn').click({force: true});
-      // wait until
-      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
-    });
-
-    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.get('.page-today-input2').type(pageName);
-      cy.screenshot(`${ssPrefix}today-add-page-name`);
-      cy.getByTestid('btn-create-memo').click();
-    });
-
-    cy.getByTestid('page-editor').should('be.visible');
-    cy.getByTestid('save-page-btn').as('save-page-btn').should('be.visible');
-    cy.waitUntil(() => {
-      // do
-      cy.get('@save-page-btn').click();
-      // wait until
-      return cy.get('@save-page-btn').then($elem => $elem.is(':disabled'));
-    });
-    cy.get('.layout-root').should('not.have.class', 'editing');
-
-    cy.collapseSidebar(true);
-    cy.waitUntilSkeletonDisappear();
-    cy.screenshot(`${ssPrefix}create-today-page`);
-  });
-
-  it('Successfully create page under specific path', () => {
-    const pageName = 'child';
-
-    cy.visit('/foo/bar');
-
-    cy.waitUntil(() => {
-      // do
-      cy.getByTestid('newPageBtn').click({force: true});
-      // wait until
-      return cy.get('body').within(() => {
-        return Cypress.$('[data-testid=page-create-modal]').is(':visible');
-      });
-    });
-
-    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.get('.rbt-input-main').should('have.value', '/foo/bar/');
-      cy.get('.rbt-input-main').type(pageName);
-      cy.screenshot(`${ssPrefix}under-path-add-page-name`);
-      cy.getByTestid('btn-create-page-under-below').click();
-    });
-
-    cy.getByTestid('page-editor').should('be.visible');
-    cy.getByTestid('save-page-btn').as('save-page-btn').should('be.visible');
-    cy.waitUntil(() => {
-      // do
-      cy.get('@save-page-btn').click();
-      // wait until
-      return cy.get('@save-page-btn').then($elem => $elem.is(':disabled'));
-    });
-    cy.get('.layout-root').should('not.have.class', 'editing');
-
-    cy.getByTestid('grw-contextual-sub-nav').should('be.visible');
-
-    cy.waitUntilSkeletonDisappear();
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}create-page-under-specific-page`);
-  });
-
-  it('Trying to create template page under the root page fail', () => {
-    cy.visit('/');
-
-    cy.waitUntil(() => {
-      // do
-      cy.getByTestid('newPageBtn').click({force: true});
-      // wait until
-      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
-    });
-
-    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.getByTestid('grw-page-create-modal-path-name').should('have.text', '/');
-
-      cy.get('#template-type').click();
-      cy.get('#template-type').next().find('button:eq(0)').click({force: true});
-      cy.getByTestid('grw-btn-edit-page').should('be.visible').click();
-    });
-    cy.get('.Toastify__toast').should('be.visible');
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}create-template-for-children-error`);
-    cy.get('.Toastify__toast').should('be.visible').within(() => {
-      cy.get('.Toastify__close-button').should('be.visible').click();
-      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
-    });
-
-    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.get('#template-type').click();
-      cy.get('#template-type').next().find('button:eq(1)').click({force: true});
-      cy.getByTestid('grw-btn-edit-page').should('be.visible').click();
-    });
-    cy.get('.Toastify__toast').should('be.visible');
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}create-template-for-descendants-error`);
-  });
-
   it('Page Deletion and PutBack is executed successfully', { scrollBehavior: false }, () => {
     cy.visit('/Sandbox/Bootstrap4');
 
@@ -342,60 +218,3 @@ context('Tag Oprations', { scrollBehavior: false }, () =>{
   });
 
 });
-
-context('Shortcuts', () => {
-  const ssPrefix = 'shortcuts';
-
-  beforeEach(() => {
-    // login
-    cy.fixture("user-admin.json").then(user => {
-      cy.login(user.username, user.password);
-    });
-  });
-
-  it('Successfully updating a page using a shortcut on a previously created page', { scrollBehavior: false }, () => {
-    const body1 = 'hello';
-    const body2 = ' world!';
-    const savePageShortcutKey = '{ctrl+s}';
-
-    cy.visit('/Sandbox/child');
-
-    cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
-    cy.waitUntil(() => {
-      // do
-      cy.get('@pageEditorModeManager').within(() => {
-        cy.get('button:nth-child(2)').click();
-      });
-      // until
-      return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
-    })
-
-    cy.get('.grw-editor-navbar-bottom').should('be.visible');
-
-    // 1st
-    cy.get('.CodeMirror').type(body1);
-    cy.get('.CodeMirror').contains(body1);
-    cy.get('.page-editor-preview-body').contains(body1);
-    cy.get('.CodeMirror').type(savePageShortcutKey);
-
-    cy.get('.Toastify__toast').should('be.visible').within(() => {
-      cy.get('.Toastify__close-button').should('be.visible').click();
-      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
-    });
-    cy.screenshot(`${ssPrefix}-update-page-1`);
-
-    cy.get('.Toastify').should('not.be.visible');
-
-    // 2nd
-    cy.get('.CodeMirror').type(body2);
-    cy.get('.CodeMirror').contains(body2);
-    cy.get('.page-editor-preview-body').contains(body2);
-    cy.get('.CodeMirror').type(savePageShortcutKey);
-
-    cy.get('.Toastify__toast').should('be.visible').within(() => {
-      cy.get('.Toastify__close-button').should('be.visible').click();
-      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
-    });
-    cy.screenshot(`${ssPrefix}-update-page-2`);
-  });
-});

+ 0 - 0
apps/app/test/cypress/integration/20-basic-features/20-basic-features--username-mention.spec.ts → apps/app/test/cypress/e2e/20-basic-features/20-basic-features--username-mention.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/21-basic-features-for-guest/21-basic-features-for-guest--access-to-page.spec.ts → apps/app/test/cypress/e2e/21-basic-features-for-guest/21-basic-features-for-guest--access-to-page.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/21-basic-features-for-guest/21-basic-features-for-guest--sticky-for-guest.spec.ts → apps/app/test/cypress/e2e/21-basic-features-for-guest/21-basic-features-for-guest--sticky-for-guest.cy.ts


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


+ 194 - 0
apps/app/test/cypress/e2e/23-editor/23-editor--saving.cy.ts

@@ -0,0 +1,194 @@
+context('PageCreateModal', () => {
+
+  const ssPrefix = 'page-create-modal-';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+  });
+
+  it("PageCreateModal is shown and closed successfully", () => {
+    cy.visit('/');
+
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
+
+    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
+      cy.screenshot(`${ssPrefix}new-page-modal-opened`);
+      cy.get('button.close').click();
+    });
+
+    cy.collapseSidebar(true, true);
+    cy.screenshot(`${ssPrefix}page-create-modal-closed`);
+  });
+
+  it("Successfully Create Today's page", () => {
+    const pageName = "Today's page";
+    cy.visit('/');
+
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
+
+    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
+      cy.get('.page-today-input2').type(pageName);
+      cy.screenshot(`${ssPrefix}today-add-page-name`);
+      cy.getByTestid('btn-create-memo').click();
+    });
+
+    cy.getByTestid('page-editor').should('be.visible');
+    cy.getByTestid('save-page-btn').as('save-page-btn').should('be.visible');
+    cy.waitUntil(() => {
+      // do
+      cy.get('@save-page-btn').click();
+      // wait until
+      return cy.get('@save-page-btn').then($elem => $elem.is(':disabled'));
+    });
+    cy.get('.layout-root').should('not.have.class', 'editing');
+
+    cy.collapseSidebar(true);
+    cy.waitUntilSkeletonDisappear();
+    cy.screenshot(`${ssPrefix}create-today-page`);
+  });
+
+  it('Successfully create page under specific path', () => {
+    const pageName = 'child';
+
+    cy.visit('/foo/bar');
+
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.get('body').within(() => {
+        return Cypress.$('[data-testid=page-create-modal]').is(':visible');
+      });
+    });
+
+    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
+      cy.get('.rbt-input-main').should('have.value', '/foo/bar/');
+      cy.get('.rbt-input-main').type(pageName);
+      cy.screenshot(`${ssPrefix}under-path-add-page-name`);
+      cy.getByTestid('btn-create-page-under-below').click();
+    });
+
+    cy.getByTestid('page-editor').should('be.visible');
+    cy.getByTestid('save-page-btn').as('save-page-btn').should('be.visible');
+    cy.waitUntil(() => {
+      // do
+      cy.get('@save-page-btn').click();
+      // wait until
+      return cy.get('@save-page-btn').then($elem => $elem.is(':disabled'));
+    });
+    cy.get('.layout-root').should('not.have.class', 'editing');
+
+    cy.getByTestid('grw-contextual-sub-nav').should('be.visible');
+
+    cy.waitUntilSkeletonDisappear();
+    cy.collapseSidebar(true);
+    cy.screenshot(`${ssPrefix}create-page-under-specific-page`);
+  });
+
+  it('Trying to create template page under the root page fail', () => {
+    cy.visit('/');
+
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
+
+    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
+      cy.getByTestid('grw-page-create-modal-path-name').should('have.text', '/');
+
+      cy.get('#template-type').click();
+      cy.get('#template-type').next().find('button:eq(0)').click({force: true});
+      cy.getByTestid('grw-btn-edit-page').should('be.visible').click();
+    });
+    cy.get('.Toastify__toast').should('be.visible');
+    cy.collapseSidebar(true);
+    cy.screenshot(`${ssPrefix}create-template-for-children-error`);
+    cy.get('.Toastify__toast').should('be.visible').within(() => {
+      cy.get('.Toastify__close-button').should('be.visible').click();
+      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
+    });
+
+    cy.getByTestid('page-create-modal').should('be.visible').within(() => {
+      cy.get('#template-type').click();
+      cy.get('#template-type').next().find('button:eq(1)').click({force: true});
+      cy.getByTestid('grw-btn-edit-page').should('be.visible').click();
+    });
+    cy.get('.Toastify__toast').should('be.visible');
+    cy.collapseSidebar(true);
+    cy.screenshot(`${ssPrefix}create-template-for-descendants-error`);
+  });
+
+});
+
+
+context('Shortcuts', () => {
+  const ssPrefix = 'shortcuts';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+  });
+
+  it('Successfully updating a page using a shortcut on a previously created page', { scrollBehavior: false }, () => {
+    const body1 = 'hello';
+    const body2 = ' world!';
+    const savePageShortcutKey = '{ctrl+s}';
+
+    cy.visit('/Sandbox/child');
+
+    cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
+    cy.waitUntil(() => {
+      // do
+      cy.get('@pageEditorModeManager').within(() => {
+        cy.get('button:nth-child(2)').click();
+      });
+      // until
+      return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
+    })
+
+    cy.get('.grw-editor-navbar-bottom').should('be.visible');
+
+    // 1st
+    cy.get('.CodeMirror').type(body1);
+    cy.get('.CodeMirror').contains(body1);
+    cy.get('.page-editor-preview-body').contains(body1);
+    cy.get('.CodeMirror').type(savePageShortcutKey);
+
+    cy.get('.Toastify__toast').should('be.visible').within(() => {
+      cy.get('.Toastify__close-button').should('be.visible').click();
+      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
+    });
+    cy.screenshot(`${ssPrefix}-update-page-1`);
+
+    cy.get('.Toastify').should('not.be.visible');
+
+    // 2nd
+    cy.get('.CodeMirror').type(body2);
+    cy.get('.CodeMirror').contains(body2);
+    cy.get('.page-editor-preview-body').contains(body2);
+    cy.get('.CodeMirror').type(savePageShortcutKey);
+
+    cy.get('.Toastify__toast').should('be.visible').within(() => {
+      cy.get('.Toastify__close-button').should('be.visible').click();
+      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
+    });
+    cy.screenshot(`${ssPrefix}-update-page-2`);
+  });
+});

+ 153 - 0
apps/app/test/cypress/e2e/23-editor/23-editor--with-navigation.cy.ts

@@ -0,0 +1,153 @@
+import path from 'path-browserify';
+
+function openEditor() {
+  cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
+  cy.waitUntil(() => {
+    // do
+    cy.get('@pageEditorModeManager').within(() => {
+      cy.get('button:nth-child(2)').click();
+    });
+    // until
+    return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
+  })
+  cy.get('.CodeMirror').should('be.visible');
+}
+
+context('Editor while uploading to a new page', () => {
+
+  const ssPrefix = 'editor-while-uploading-';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+  });
+
+  // for https://redmine.weseek.co.jp/issues/122040
+  it('should not be cleared and should prevent GrantSelector from modified', { scrollBehavior: false }, () => {
+    cy.visit('/Sandbox/for-122040');
+
+    openEditor();
+
+    cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-1`);
+
+    // input the body
+    const body = 'Hello World!';
+    cy.get('.CodeMirror').type(body + '\n\n');
+    cy.get('.CodeMirror').should('contain.text', body);
+
+    // open GrantSelector
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('grw-grant-selector').within(() => {
+        cy.get('button.dropdown-toggle').click({force: true});
+      });
+      // wait until
+      return cy.getByTestid('grw-grant-selector').within(() => {
+        return Cypress.$('.dropdown-menu.show').is(':visible');
+      });
+    });
+
+    // Select "Only me"
+    cy.getByTestid('grw-grant-selector').within(() => {
+      // click "Only me"
+      cy.get('.dropdown-menu.show').find('.dropdown-item').should('have.length', 4).then((menuItems) => {
+        menuItems[2].click();
+      });
+    });
+
+    cy.getByTestid('grw-grant-selector').find('.dropdown-toggle').should('contain.text', 'Only me');
+    cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-2`);
+
+    // drag-drop a file
+    const filePath = path.relative('/', path.resolve(Cypress.spec.relative, '../assets/example.txt'));
+    cy.get('.dropzone').selectFile(filePath, { action: 'drag-drop' });
+
+    // expect
+    cy.get('.CodeMirror').should('contain.text', body);
+    cy.get('.CodeMirror').should('contain.text', '[example.txt](/attachment/');
+    cy.getByTestid('grw-grant-selector').find('.dropdown-toggle').should('contain.text', 'Only me');
+    cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-3`);
+  });
+
+});
+
+context.skip('Editor while navigation', () => {
+
+  const ssPrefix = 'editor-while-navigation-';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+  });
+
+  // for https://redmine.weseek.co.jp/issues/115285
+  it('Successfully updating the page body', { scrollBehavior: false }, () => {
+    const page1Path = '/Sandbox/for-115285/page1';
+    const page2Path = '/Sandbox/for-115285/page2';
+
+    cy.visit(page1Path);
+
+    openEditor();
+
+    // page1
+    const bodyHello = 'hello';
+    cy.get('.CodeMirror').type(bodyHello);
+    cy.get('.CodeMirror').should('contain.text', bodyHello);
+    cy.get('.page-editor-preview-body').should('contain.text', bodyHello);
+    cy.getByTestid('page-editor').should('be.visible');
+    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page1`);
+
+    // save page1
+    cy.getByTestid('save-page-btn').click();
+
+    // open duplicate modal
+    cy.waitUntil(() => {
+      // do
+      cy.get('#grw-subnav-container').within(() => {
+        cy.getByTestid('open-page-item-control-btn').find('button').click({force: true});
+      });
+      // wait until
+      return cy.getByTestid('page-item-control-menu').then($elem => $elem.is(':visible'))
+    });
+    cy.getByTestid('open-page-duplicate-modal-btn').filter(':visible').click({force: true});
+
+    // duplicate and navigate to page1
+    cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
+      cy.get('input.form-control').clear();
+      cy.get('input.form-control').type(page2Path);
+      cy.getByTestid('btn-duplicate').click();
+    })
+
+    openEditor();
+
+    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page2`);
+
+    // type (without save)
+    const bodyWorld = ' world!!'
+    cy.get('.CodeMirror').type(`${bodyWorld}`);
+    cy.get('.CodeMirror').should('contain.text', `${bodyHello}${bodyWorld}`);
+    cy.get('.page-editor-preview-body').should('contain.text', `${bodyHello}${bodyWorld}`);
+    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page2-modified`);
+
+    // create a link to page1
+    cy.get('.CodeMirror').type('\n\n[page1](./page1)');
+
+    // go to page1
+    cy.get('.page-editor-preview-body').within(() => {
+      cy.get("a:contains('page1')").click();
+    });
+
+    openEditor();
+
+    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page1-returned`);
+
+    // expect
+    cy.get('.CodeMirror').should('contain.text', bodyHello);
+    cy.get('.CodeMirror').should('not.contain.text', bodyWorld); // text that added to page2
+    cy.get('.CodeMirror').should('not.contain.text', 'page1'); // text that added to page2
+  });
+});

+ 1 - 0
apps/app/test/cypress/e2e/23-editor/assets/example.txt

@@ -0,0 +1 @@
+example.txt

+ 0 - 0
apps/app/test/cypress/integration/30-search/30-search--search.spec.ts → apps/app/test/cypress/e2e/30-search/30-search--search.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/40-admin/40-admin--access-to-admin-page.spec.ts → apps/app/test/cypress/e2e/40-admin/40-admin--access-to-admin-page.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/50-sidebar/50-sidebar--access-to-side-bar.spec.ts → apps/app/test/cypress/e2e/50-sidebar/50-sidebar--access-to-side-bar.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/50-sidebar/50-sidebar--switching-sidebar-mode.spec.ts → apps/app/test/cypress/e2e/50-sidebar/50-sidebar--switching-sidebar-mode.cy.ts


+ 0 - 0
apps/app/test/cypress/integration/60-home/60-home--home.spec.ts → apps/app/test/cypress/e2e/60-home/60-home--home.cy.ts


+ 2 - 0
package.json

@@ -61,6 +61,7 @@
     "@types/eslint": "^8.37.0",
     "@types/estree": "^1.0.1",
     "@types/node": "^17.0.43",
+    "@types/path-browserify": "^1.0.0",
     "@types/rewire": "^2.5.28",
     "@typescript-eslint/eslint-plugin": "^5.59.7",
     "@typescript-eslint/parser": "^5.59.7",
@@ -80,6 +81,7 @@
     "eslint-plugin-vitest": "^0.2.3",
     "glob": "^8.1.0",
     "mock-require": "^3.0.3",
+    "path-browserify": "^1.0.1",
     "postcss": "^8.4.5",
     "postcss-scss": "^4.0.3",
     "reg-keygen-git-hash-plugin": "^0.11.1",

+ 5 - 0
yarn.lock

@@ -3974,6 +3974,11 @@
   resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
   integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
 
+"@types/path-browserify@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@types/path-browserify/-/path-browserify-1.0.0.tgz#294ec6e88b6b0d340a3897b7120e5b393f16690e"
+  integrity sha512-XMCcyhSvxcch8b7rZAtFAaierBYdeHXVvg2iYnxOV0MCQHmPuRRmGZPFDRzPayxcGiiSL1Te9UIO+f3cuj0tfw==
+
 "@types/pixelmatch@^5.2.2":
   version "5.2.4"
   resolved "https://registry.yarnpkg.com/@types/pixelmatch/-/pixelmatch-5.2.4.tgz#ca145cc5ede1388c71c68edf2d1f5190e5ddd0f6"