diff --git a/.gitignore b/.gitignore
index 19c8ba147..d3233ecbb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,4 @@ packages/server/scripts/local
!**/.yarn/versions
.claude
+stats.html
diff --git a/cypress/e2e/a-journal/002-assign_reviewers_spec.cy.js b/cypress/e2e/a-journal/002-assign_reviewers_spec.cy.js
index c9b4bcc66..92d6ff9fe 100644
--- a/cypress/e2e/a-journal/002-assign_reviewers_spec.cy.js
+++ b/cypress/e2e/a-journal/002-assign_reviewers_spec.cy.js
@@ -41,6 +41,8 @@ describe('Editor assigning reviewers', () => {
// Go to dashboard and verify number of invited reviewer
Menu.clickDashboard()
- cy.getByDataTestId('donut-center-label').contains('6')
+ cy.getByDataTestId('statusCounts')
+ .find('[data-testid="reviewer-status-square"]')
+ .should('have.length', 6)
})
})
diff --git a/cypress/e2e/a-journal/003-review_spec.cy.js b/cypress/e2e/a-journal/003-review_spec.cy.js
index 2c627a0b6..08b5efbeb 100644
--- a/cypress/e2e/a-journal/003-review_spec.cy.js
+++ b/cypress/e2e/a-journal/003-review_spec.cy.js
@@ -50,20 +50,20 @@ describe('Completing reviews', () => {
cy.wait(1000)
DashboardPage.clickDashboardTab(2)
- cy.get('[fill="#56b984"]')
- .should('be.visible')
- .trigger('mouseover', { force: true })
- cy.contains('Completed: 3')
- cy.wait(1000)
- cy.get('[fill="#fff2cd"]').should('be.visible').trigger('mouseover')
- cy.contains('Invited: 1')
- cy.get('[fill="#d7efd4"]').should('be.visible').trigger('mouseover')
- cy.contains('Accepted: 1')
-
- cy.get('[fill="#c23d20"]').should('be.visible').trigger('mouseover')
- cy.contains('Declined: 1')
-
- cy.get('[data-testid="control-panel-team"]').click()
+ cy.getByDataTestId('statusCounts')
+ .find('[role="img"][aria-label$="Completed"]')
+ .should('have.length', 3)
+ cy.getByDataTestId('statusCounts')
+ .find('[role="img"][aria-label$="Invited"]')
+ .should('have.length', 1)
+ cy.getByDataTestId('statusCounts')
+ .find('[role="img"][aria-label$="Accepted"]')
+ .should('have.length', 1)
+ cy.getByDataTestId('statusCounts')
+ .find('[role="img"][aria-label$="Declined"]')
+ .should('have.length', 1)
+
+ cy.get('[data-testid="control-link"]').click()
cy.awaitDisappearSpinner()
cy.get(
'[data-testid=kanban] > :nth-child(1) > [data-testid=kanban-cards-wrapper] > [data-testid=kanban-card]',
@@ -92,7 +92,9 @@ const doReview = (name, reviewData) => {
// Accpet Review Request Workflow
if (reviewData.verdict === 'accept') {
DashboardPage.clickAcceptReviewButton()
- cy.contains('button', 'Do Review').should('exist')
+ cy.contains('Accept this review invitation?').should('be.visible')
+ cy.contains('button', 'OK').click()
+ DashboardPage.getDoReviewButton().should('contain', 'Do Review')
// Only do the review if there'a comment present
if (reviewData.comment) {
@@ -116,6 +118,7 @@ const doReview = (name, reviewData) => {
// Verify the review got completed
cy.get('nav').contains('Dashboard').click()
+ cy.url().should('contain', '/dashboard/reviews')
DashboardPage.getDoReviewButton().should('contain', 'View')
cy.getByDataTestId('menu-user').click()
cy.contains('Logout').click()
@@ -125,6 +128,8 @@ const doReview = (name, reviewData) => {
// Reject Review Request Workflow
if (reviewData.verdict === 'reject') {
DashboardPage.clickRejectReviewButton()
+ cy.contains('Decline this review invitation?').should('be.visible')
+ cy.contains('button', 'OK').click()
DashboardPage.getDoReviewButton().should('not.exist')
cy.getByDataTestId('menu-user').click()
cy.contains('Logout').click()
diff --git a/cypress/e2e/a-journal/004-assigning_editor_spec.cy.js b/cypress/e2e/a-journal/004-assigning_editor_spec.cy.js
index 631c4cdf8..eecc7e5ee 100644
--- a/cypress/e2e/a-journal/004-assigning_editor_spec.cy.js
+++ b/cypress/e2e/a-journal/004-assigning_editor_spec.cy.js
@@ -21,7 +21,7 @@ describe('Assigning editors and decision reject', () => {
cy.wait(1000)
Menu.clickManuscripts()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
cy.wait(1000)
ControlPage.clickAssignSeniorEditorDropdown()
diff --git a/cypress/e2e/a-journal/005-decision_spec.cy.js b/cypress/e2e/a-journal/005-decision_spec.cy.js
index dceaa9838..3d74de361 100644
--- a/cypress/e2e/a-journal/005-decision_spec.cy.js
+++ b/cypress/e2e/a-journal/005-decision_spec.cy.js
@@ -25,7 +25,7 @@ describe('Completing a decision', () => {
cy.wait(2000)
DashboardPage.clickManuscriptNavButton()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
ControlPage.getAssignSeniorEditorDropdown().click({ force: true })
cy.contains(name.role.seniorEditor).click({ force: true })
})
@@ -61,7 +61,7 @@ describe('Completing a decision', () => {
/* View Decision as an Author */
cy.login(name.role.author, dashboard) // Login as an Author
- DashboardPage.getSubmittedManuscript().click() // Click on first MySubmission
+ DashboardPage.clickSubmissionActionLink() // Click on first MySubmission
// Verify Decision Content
DashboardPage.getDecisionField(0).should('contain', decisionTextContent)
@@ -77,9 +77,7 @@ describe('Completing a decision', () => {
)
SubmissionFormPage.clickSubmitResearch()
SubmissionFormPage.clickSubmitYourManuscript()
- DashboardPage.getSubmittedManuscript()
- .contains('test pdf')
- .should('exist') // Verify new submission got created
+ DashboardPage.getSubmissionTitle().contains('test pdf').should('exist') // Verify new submission got created
})
})
diff --git a/cypress/e2e/b-colab-prc/102-manuscript_page_label_and_tooltip_spec.cy.js b/cypress/e2e/b-colab-prc/102-manuscript_page_label_and_tooltip_spec.cy.js
index 8f47bdc5d..a9fc53b7d 100644
--- a/cypress/e2e/b-colab-prc/102-manuscript_page_label_and_tooltip_spec.cy.js
+++ b/cypress/e2e/b-colab-prc/102-manuscript_page_label_and_tooltip_spec.cy.js
@@ -27,22 +27,16 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
it('verifies the selected label after choosing from the dropdown', () => {
cy.contains('div', 'Manuscripts').should('exist')
- // Click the Select button
- ManuscriptsPage.getSelectButton().should('be.visible')
- ManuscriptsPage.clickArticleLabel(-1)
+ ManuscriptsPage.getArticleLabel().should('be.visible')
// Function to select a label and verify it
const selectLabelAndVerify = label => {
- cy.getByDataTestId('label-dropdown-element').click()
- cy.screenshot('before-dropdown')
- cy.get('body').then($body => {
- if (!$body.find('[data-testid=label-dropdown-menu]').length) {
- cy.log('Dropdown not found in body!')
- }
- })
-
- cy.get('[data-testid=label-dropdown-menu]').contains(label).click()
- ManuscriptsPage.getLabelDropdown().should('contain', label)
+ ManuscriptsPage.clickArticleLabel(-1)
+ cy.getByDataTestId('select-dropdown')
+ .find('[data-testid="editable-option"]')
+ .contains(label)
+ .click({ force: true })
+ ManuscriptsPage.getArticleLabel().eq(-1).should('contain', label)
Menu.clickManuscriptsAndAssertPageLoad()
}
@@ -51,11 +45,10 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
labels.forEach(selectLabelAndVerify)
// Unset the custom label
- cy.get('[data-testid=label-dropdown-styled-button]').eq(0).click()
- cy.get('[data-testid=manuscripts-table-styled-button]').should(
- 'contain',
- 'Select',
- )
+ ManuscriptsPage.clickArticleLabelClear(-1)
+ ManuscriptsPage.getArticleLabel()
+ .eq(-1)
+ .should('not.contain', 'Ready to publish')
})
context('tooltip tests', () => {
@@ -69,7 +62,8 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
it('check no tooltip for empty abstract', () => {
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
- ManuscriptsPage.getTooltipIcon().should('not.exist')
+ ManuscriptsPage.getTooltipIcon().should('be.visible').click()
+ ManuscriptsPage.getTooltipText().should('contain', 'No abstract provided')
})
it('check tooltip text', () => {
@@ -78,28 +72,29 @@ describe('Checking manuscripts page: label selection and tooltip', () => {
SubmissionFormPage.fillInAbstractColab(data.abstract)
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.getTooltipText().should('not.exist')
- ManuscriptsPage.getTooltipIcon()
- .should('be.visible')
- .trigger('mouseover')
+ ManuscriptsPage.getTooltipIcon().should('be.visible').click()
ManuscriptsPage.getTooltipText()
.should('contain', data.abstract)
.and('not.contain', '
')
})
})
- it('check length for the tooltip text, to be less than 1000', () => {
+ it('truncates a long abstract to 60 words', () => {
+ const longAbstract = Array.from(
+ { length: 65 },
+ (_, i) => `word${i + 1}`,
+ ).join(' ')
+
cy.contains('Continue Submission').click()
- cy.fixture('submission_form_data').then(data => {
- SubmissionFormPage.fillInAbstractColab(
- data.abstractWithMoreThan1000Characters,
- )
- Menu.clickManuscriptsAndAssertPageLoad()
- ManuscriptsPage.getTooltipText().should('not.exist')
- ManuscriptsPage.getTooltipIcon().trigger('mouseover')
- ManuscriptsPage.getTooltipText()
- .should('contain', '...')
- .should('have.lengthOf.lessThan', 1000)
- })
+ SubmissionFormPage.fillInAbstractColab(longAbstract)
+ Menu.clickManuscriptsAndAssertPageLoad()
+ ManuscriptsPage.getTooltipText().should('not.exist')
+ ManuscriptsPage.getTooltipIcon().click()
+ ManuscriptsPage.getTooltipText()
+ .should('contain', '...')
+ .should($el => {
+ expect($el.text().trim().split(/\s+/).length).to.be.at.most(61)
+ })
})
})
})
diff --git a/cypress/e2e/b-colab-prc/103-manuscripts_page_filter_sort_archive_spec.cy.js b/cypress/e2e/b-colab-prc/103-manuscripts_page_filter_sort_archive_spec.cy.js
index 63087c8c9..6effc8b80 100644
--- a/cypress/e2e/b-colab-prc/103-manuscripts_page_filter_sort_archive_spec.cy.js
+++ b/cypress/e2e/b-colab-prc/103-manuscripts_page_filter_sort_archive_spec.cy.js
@@ -81,7 +81,7 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
context('filter and sort articles', () => {
it('filter per status', () => {
ManuscriptsPage.getTableRowsCount().should('eq', 3)
- ManuscriptsPage.clickStatus(-1)
+ ManuscriptsPage.filterColumnByValue('status', 'Unsubmitted')
ManuscriptsPage.getTableRowsCount().should('eq', 2)
ManuscriptsPage.getStatus(0).should('contain', 'Unsubmitted')
cy.url().should('contain', 'new')
@@ -97,18 +97,15 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
cy.url().should('contain', 'readyToEvaluate')
ManuscriptsPage.getLabelRow(0).should('contain', 'Ready to evaluate')
ManuscriptsPage.getLabelRow(1).should('contain', 'Ready to evaluate')
- ManuscriptsPage.getLabelRow(2).should('contain', 'Ready to evaluate')
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectCustomStatus('Evaluated')
ManuscriptsPage.getTableRowsCount().should('eq', 1)
cy.url().should('contain', 'evaluated')
ManuscriptsPage.getLabelRow(0).should('contain', 'Evaluated')
- ManuscriptsPage.getLabelRow(1).should('contain', 'Evaluated')
Menu.clickManuscriptsAndAssertPageLoad()
ManuscriptsPage.selectCustomStatus('Ready to publish')
ManuscriptsPage.assertNoTableRows()
cy.url().should('contain', 'readyToPublish')
- ManuscriptsPage.getLabelRow(0).should('contain', 'Ready to publish')
})
})
@@ -134,7 +131,7 @@ describe('manuscripts page tests - Filter, sort, bulk select, archive', () => {
ManuscriptsPage.clickDelete()
ManuscriptsPage.getConfirmationMessageForBulkDelete().should(
'contain',
- 'Please confirm you wish to archive the selected manuscripts.',
+ 'Archive 2 manuscripts?',
)
ManuscriptsPage.clickConfirm()
ManuscriptsPage.getConfirmationMessageForBulkDelete().should('not.exist')
diff --git a/cypress/e2e/b-colab-prc/104-control_page_spec.cy.js b/cypress/e2e/b-colab-prc/104-control_page_spec.cy.js
index bea358245..31cd62123 100644
--- a/cypress/e2e/b-colab-prc/104-control_page_spec.cy.js
+++ b/cypress/e2e/b-colab-prc/104-control_page_spec.cy.js
@@ -175,9 +175,10 @@ describe('control page tests', () => {
cy.login(name.role.admin, manuscripts)
cy.awaitDisappearSpinner()
Menu.clickManuscriptsAndAssertPageLoad()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
ControlPage.getAssignSeniorEditorDropdown().should('be.visible')
+ cy.awaitDisappearSpinner()
ControlPage.inviteReviewer(name.role.reviewers[1])
cy.reload()
cy.get('input[value = "isCollaborative"]').should('not.exist')
@@ -188,8 +189,10 @@ describe('control page tests', () => {
cy.wait(1000)
DashboardPage.clickDashboardTab(1)
DashboardPage.clickAcceptReviewButton()
+ cy.contains('Accept this review invitation?').should('be.visible')
+ cy.contains('button', 'OK').click()
- cy.contains('button', 'Do Review').should('exist')
+ DashboardPage.getDoReviewButton().should('contain', 'Do Review')
DashboardPage.clickDoReview()
cy.fixture('submission_form_data').then(data => {
cy.contains('div', 'Metadata').should('be.visible')
@@ -202,7 +205,7 @@ describe('control page tests', () => {
ReviewPage.clickSubmitButton()
ReviewPage.clickConfirmSubmitButton()
- cy.get('[name="submission.$title"]').contains('test pdf')
+ cy.get('[data-testid="submission.$title"]').contains('test pdf')
})
})
})
@@ -211,7 +214,7 @@ describe('control page tests', () => {
cy.fixture('role_names').then(name => {
cy.login(name.role.admin, manuscripts)
cy.awaitDisappearSpinner()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
ControlPage.getAssignSeniorEditorDropdown().should('be.visible')
})
@@ -223,7 +226,7 @@ describe('control page tests', () => {
ControlPage.getHideReviewerNameCheckbox().should('be.checked')
cy.fixture('role_names').then(name => {
cy.login(name.role.reviewers[1], dashboard)
- cy.get('[data-testid="submission.$title"]:last').click()
+ DashboardPage.clickDoReview()
cy.get('[data-testid=tab-container]').contains('Review').click()
ControlPage.getReviewerName().should(
'not.contain',
@@ -239,7 +242,7 @@ describe('control page tests', () => {
ControlPage.getHideReviewerNameCheckbox('should', 'not.be.checked')
cy.fixture('role_names').then(name => {
cy.login(name.role.reviewers[1], dashboard)
- cy.get('[data-testid="submission.$title"]:last').click()
+ DashboardPage.clickDoReview()
cy.get('[data-testid=tab-container]').contains('Review').click()
ControlPage.getReviewerName().should('contain', name.role.reviewers[1])
})
@@ -304,7 +307,7 @@ describe('control page tests', () => {
cy.awaitDisappearSpinner()
DashboardPage.getHeader().should('be.visible')
Menu.clickManuscriptsAndAssertPageLoad()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
cy.awaitDisappearSpinner()
cy.contains('Tasks & Notifications').click()
})
diff --git a/cypress/e2e/b-colab-prc/105-review_and_decision_page_spec.cy.js b/cypress/e2e/b-colab-prc/105-review_and_decision_page_spec.cy.js
index b6fae20ff..89f41913b 100644
--- a/cypress/e2e/b-colab-prc/105-review_and_decision_page_spec.cy.js
+++ b/cypress/e2e/b-colab-prc/105-review_and_decision_page_spec.cy.js
@@ -96,7 +96,9 @@ Cypress.Commands.add(
cy.wait(1000)
DashboardPage.clickDashboardTab(1)
DashboardPage.clickAcceptReviewButton()
- cy.contains('button', 'Do Review').should('be.visible')
+ cy.contains('Accept this review invitation?').should('be.visible')
+ cy.contains('button', 'OK').click()
+ DashboardPage.getDoReviewButton().should('contain', 'Do Review')
DashboardPage.clickDoReviewAndVerifyPageLoaded()
cy.contains('div', 'Metadata').should('be.visible')
@@ -121,7 +123,7 @@ Cypress.Commands.add(
Cypress.Commands.add('submitDecision', (decisionText, decisionAction) => {
cy.awaitDisappearSpinner()
- ManuscriptsPage.selectOptionWithText('Control')
+ ManuscriptsPage.clickControlLink()
ControlPage.clickDecisionTab(1)
ControlPage.fillInDecision(decisionText)
diff --git a/cypress/e2e/b-colab-prc/107-new_manuscript_version_spec.cy.js b/cypress/e2e/b-colab-prc/107-new_manuscript_version_spec.cy.js
index 1b95f83c3..854d0bc29 100644
--- a/cypress/e2e/b-colab-prc/107-new_manuscript_version_spec.cy.js
+++ b/cypress/e2e/b-colab-prc/107-new_manuscript_version_spec.cy.js
@@ -50,7 +50,7 @@ describe('checking manuscript version', () => {
cy.wait(1000)
cy.login(name.role.author, dashboard)
/* Click on first MySubmission */
- DashboardPage.getSubmittedManuscript().click()
+ DashboardPage.clickSubmissionActionLink()
/* Verify Decision Content */
DashboardPage.getDecisionField(0).should('contain', decisionTextContent)
@@ -76,9 +76,7 @@ describe('checking manuscript version', () => {
SubmissionFormPage.clickSubmitResearch()
SubmissionFormPage.clickSubmitYourManuscript()
/* Verify new submission got created */
- DashboardPage.getSubmittedManuscript()
- .contains('test pdf')
- .should('exist')
+ DashboardPage.getSubmissionTitle().contains('test pdf').should('exist')
/* Login as editor and check the new version submission form */
cy.login(name.role.seniorEditor, dashboard)
diff --git a/cypress/e2e/c-elife-single_form/202-modify_submission_form_spec.cy.js b/cypress/e2e/c-elife-single_form/202-modify_submission_form_spec.cy.js
index c2983ed61..2f39fdfd1 100644
--- a/cypress/e2e/c-elife-single_form/202-modify_submission_form_spec.cy.js
+++ b/cypress/e2e/c-elife-single_form/202-modify_submission_form_spec.cy.js
@@ -28,7 +28,7 @@ describe('validating required field and doi values in submission form', () => {
})
ManuscriptsPage.getTableHead().should('be.visible')
Menu.clickManuscripts()
- ManuscriptsPage.getOptionsElifeText('Evaluation').click()
+ ManuscriptsPage.clickEvaluationLink()
})
context('check the Submission form based on form builder', () => {
@@ -75,7 +75,7 @@ describe('validating required field and doi values in submission form', () => {
SubmissionFormPage.clickElifeSubmitResearch()
// check for the submission form contains doi
- ManuscriptsPage.getOptionsElifeText('Evaluation').click()
+ ManuscriptsPage.clickEvaluationLink()
SubmissionFormPage.getDoi().should(
'have.value',
data.doi.split('https://doi.org/')[1],
diff --git a/cypress/e2e/c-elife-single_form/203-manuscripts_page_spec.cy.js b/cypress/e2e/c-elife-single_form/203-manuscripts_page_spec.cy.js
index c85503be0..11aed82a4 100644
--- a/cypress/e2e/c-elife-single_form/203-manuscripts_page_spec.cy.js
+++ b/cypress/e2e/c-elife-single_form/203-manuscripts_page_spec.cy.js
@@ -44,7 +44,7 @@ describe('Manuscripts page tests', () => {
ManuscriptsPage.getEvaluationButton()
.scrollIntoView()
.should('be.visible')
- ManuscriptsPage.getOptionsElifeText('Publish').should('not.exist')
+ ManuscriptsPage.getPublishLink().should('not.exist')
})
})
@@ -196,8 +196,8 @@ describe('Manuscripts page tests', () => {
ManuscriptsPage.getEvaluationButton()
.scrollIntoView()
.should('be.visible')
- ManuscriptsPage.getOptionsElife().should('not.contain', 'Control')
- ManuscriptsPage.getOptionsElife().should('contain', 'Publish')
+ ManuscriptsPage.getControlLink().should('not.exist')
+ ManuscriptsPage.getPublishLink().should('exist')
})
it('submission details should be visible', () => {
diff --git a/cypress/e2e/c-elife-single_form/204-publish_submission_form_field.cy.js b/cypress/e2e/c-elife-single_form/204-publish_submission_form_field.cy.js
index 9321c3fda..c2d5a53c8 100644
--- a/cypress/e2e/c-elife-single_form/204-publish_submission_form_field.cy.js
+++ b/cypress/e2e/c-elife-single_form/204-publish_submission_form_field.cy.js
@@ -52,10 +52,12 @@ describe('Update the submission form field', () => {
// Verify that changes are autosaved
SubmissionFormPage.getTitleField().should('have.value', data.description)
SubmissionFormPage.clickSubmitResearchAndWaitPageLoadElife()
- ManuscriptsPage.getOptionsElifeText('Evaluation').click()
+ ManuscriptsPage.clickEvaluationLink()
SubmissionFormPage.clickSubmitResearchAndWaitPageLoadElife()
cy.intercept('/graphql').as('getResponse')
- ManuscriptsPage.getOptionsElifeText('Publish').click()
+ ManuscriptsPage.clickPublishLink()
+ cy.contains('Publish this manuscript?').should('be.visible')
+ cy.contains('button', 'OK').click()
cy.wait('@getResponse').its('response').should('deep.include', {
statusCode: 200,
statusMessage: 'OK',
diff --git a/cypress/e2e/ncrc/05-manuscripts_page_spec.cy.js b/cypress/e2e/ncrc/05-manuscripts_page_spec.cy.js
index bed4e5063..7e9d79060 100644
--- a/cypress/e2e/ncrc/05-manuscripts_page_spec.cy.js
+++ b/cypress/e2e/ncrc/05-manuscripts_page_spec.cy.js
@@ -1,4 +1,4 @@
-/* eslint-disable promise/always-return, promise/catch-or-return */
+/* eslint-disable promise/always-return */
/* eslint-disable cypress/no-unnecessary-waiting */
import { manuscripts } from '../../support/routes'
diff --git a/cypress/page-object/dashboard-page.js b/cypress/page-object/dashboard-page.js
index 6c7bde677..10af84c63 100644
--- a/cypress/page-object/dashboard-page.js
+++ b/cypress/page-object/dashboard-page.js
@@ -14,7 +14,7 @@ const SUBMISSION_FILE_UPLOAD_INPUT = 'input[type=file]'
const SUBMISSION_CREATED = 'Submission created'
/* My Submissions */
-const SUBMITTED_MANUSCRIPTS = '[data-testid=clickable-manuscripts-row]'
+const SUBMISSION_ACTION_LINK = 'submission-action-link'
const CREATE_NEW_VERSION_BUTTON = 'create-new-manuscript-version-button'
/* Submitted Info */
@@ -22,29 +22,25 @@ const DECISION_FIELDS =
':nth-child(1) > [data-testid=section] > [data-testid=section] > div'
// 'To Review section'
-const DO_REVIEW_BUTTON = '[data-testid="reviewerLinks"] button'
+const DO_REVIEW_BUTTON = 'review-action-link'
const ACCEPT_REVIEW_BUTTON = 'accept-review'
const REJECT_REVIEW_BUTTON = 'reject-review'
// 'Manuscripts I'm editor of' section
-const CONTROL_BUTTON = 'control-panel-team'
+const CONTROL_BUTTON = 'control-link'
const MANUSCRIPT_NAV_BUTTON = '[href*="/admin/manuscripts"]'
const INVITED_REVIEWS_STATUS = 'invited'
const COMPLETED_REVIEWS_STATUS = 'completed'
const REJECTED_REVIEWS_STATUS = 'rejected'
const ACCEPTED_REVIEWS_STATUS = 'accepted'
const VERSION_TITLE = 'VersionTitle__Root-sc'
-const ARTICLE_LINK = '[data-testid="reviewerLinks"] button'
export const DashboardPage = {
- getSubmittedManuscript() {
- return cy.get(SUBMITTED_MANUSCRIPTS)
+ getSubmissionActionLink() {
+ return cy.getByDataTestId(SUBMISSION_ACTION_LINK)
},
- getSubmittedManuscripts(nth) {
- return cy.get(SUBMITTED_MANUSCRIPTS).eq(nth)
- },
- clickSubmittedManuscript(nth) {
- this.getSubmittedManuscripts(nth).click()
+ clickSubmissionActionLink() {
+ this.getSubmissionActionLink().click()
},
getSubmitButton() {
return cy.get(BUTTON).contains(SUBMISSION_BUTTON)
@@ -77,7 +73,7 @@ export const DashboardPage = {
return this.getSubmitButton().click()
},
getSectionPlaceholder(nth) {
- return cy.getByDataTestId('placeholder').eq(nth)
+ return cy.getByDataTestId('empty-manuscripts-table-placeholder').eq(nth)
},
getCreateNewVersionButton() {
return cy.getByDataTestId(CREATE_NEW_VERSION_BUTTON)
@@ -118,10 +114,9 @@ export const DashboardPage = {
},
clickRejectReviewButton() {
this.getRejectReviewButton().click({ force: true })
- cy.reload()
},
getDoReviewButton() {
- return cy.get(DO_REVIEW_BUTTON)
+ return cy.getByDataTestId(DO_REVIEW_BUTTON)
},
clickDoReview() {
this.getDoReviewButton().click({ force: true })
@@ -147,7 +142,7 @@ export const DashboardPage = {
return cy.getByContainsClass(VERSION_TITLE)
},
getCompletedReviewButton() {
- return cy.get(ARTICLE_LINK)
+ return this.getDoReviewButton()
},
clickCompletedReviewButton() {
this.getCompletedReviewButton().click({ force: true })
diff --git a/cypress/page-object/manuscripts-page.js b/cypress/page-object/manuscripts-page.js
index a10e17f86..695b55bcd 100644
--- a/cypress/page-object/manuscripts-page.js
+++ b/cypress/page-object/manuscripts-page.js
@@ -15,47 +15,55 @@ const EVALUATION_BUTTON = '[href*=evaluation]'
const CREATED_CARET = 'Carets__Caret'
const TABLE_HEADER = '[class*=Table__Header]'
const ARTICLE_TITLE = '[class*=Table__Row]>td:nth-child(1)'
-const ARTICLE_ID = '[name="submission.articleId"]'
-const ARTICLE_LABEL = '[name="submission.$customStatus"]'
-const DROPDOWN_LABEL = '[data-testid=label-dropdown-base-dropdown]'
+const ARTICLE_ID = '[data-testid="submission.articleId"]'
+const ARTICLE_LABEL =
+ '[data-testid="submission.$customStatus"] [data-testid="editable-option-select"]'
const ARTICLE_TOPIC = '[class*=Table__Cell] > [title]'
-const TABLE_ROW = '[data-testid=manuscripts-row]'
+const TABLE_ROW = '.ant-table-tbody .ant-table-row'
const TABLE_CELL = 'Table__Cell'
-const LABEL = '[name="submission.$customStatus"]'
-const CONFIRM_BUTTON =
- '[data-testid="confirmation-modal-container"] button:nth-child(1)'
-const ARTICLE_CHECKBOX =
- '[data-testid=row-item-checkbox]label > [type*=checkbox]'
-
-const SELECT_ALL_CHECKBOX = '[type=checkbox]'
+const ARTICLE_CHECKBOX = '.ant-table-tbody .ant-checkbox-wrapper'
+const SELECT_ALL_CHECKBOX = '.ant-table-thead .ant-checkbox-wrapper'
const EDITOR_NAME_CELL = 'style__StyledAuthor'
-const TOOLTIP_TEXT = 'rc-tooltip-inner'
-const ARTICLES_COUNT = '[data-testid=pagination-container] > div > strong'
+const ARTICLES_COUNT = '.ant-pagination-total-text strong'
const PAGINATION_PAGE_BUTTON = 'Page '
-const CONFIRMATION_MESSAGE =
- '[data-testid="confirmation-modal-container"] [data-testid="message-string"]'
+const CONFIRMATION_MESSAGE = '.ant-modal-confirm-content'
const IMPORT_CONFIRMATION_POPUP = '[class*=Toastify] > [role=alert]'
// const CONTROL = '[href*=decision]'
const DROPDOWN_OPTION = '[data-testid="select-option"]'
export const ManuscriptsPage = {
- getManuscriptsOptionsList() {
- return cy.getByDataTestId('action-link')
+ getEvaluationLink() {
+ return cy.getByDataTestId('evaluation-action-link').first()
+ },
+ clickEvaluationLink() {
+ this.getEvaluationLink().click()
+ },
+ getControlLink() {
+ return cy.getByDataTestId('control-action-link')
+ },
+ clickControlLink() {
+ this.getControlLink().click()
},
- selectOptionWithText(text) {
- this.getManuscriptsOptionsList().contains(text).click()
+ getViewLink() {
+ return cy.getByDataTestId('view-action-link')
},
- getOptionWithText(text) {
- return this.getManuscriptsOptionsList().contains(text)
+ clickViewLink() {
+ this.getViewLink().click()
},
- getOptionsElife() {
- return cy.getByDataTestId('action-link')
+ getProductionLink() {
+ return cy.getByDataTestId('production-action-link')
},
- getOptionsElifeText(text) {
- return cy.getByDataTestId('action-link').contains(text)
+ clickProductionLink() {
+ this.getProductionLink().click()
+ },
+ getPublishLink() {
+ return cy.getByDataTestId('publish-action-link')
+ },
+ clickPublishLink() {
+ this.getPublishLink().click()
},
getSubmitButton() {
return cy.get(BUTTON).contains('New submission')
@@ -79,7 +87,7 @@ export const ManuscriptsPage = {
return cy.get('h1')
},
getEvaluationButton() {
- return cy.contains('button', 'Evaluation')
+ return this.getEvaluationLink()
},
getNthEvaluationButton(nth) {
return cy.get(EVALUATION_BUTTON).eq(nth)
@@ -127,7 +135,7 @@ export const ManuscriptsPage = {
return cy.getByContainsClass(CREATED_CARET).eq(nth)
},
getAuthorField(nth) {
- return cy.getByDataTestId('usercombo-primary').eq(nth)
+ return cy.getByDataTestId('person-name').eq(nth)
},
getAuthor(nth) {
return this.getAuthorField(nth).invoke('text')
@@ -138,11 +146,8 @@ export const ManuscriptsPage = {
getStatus(nth) {
return this.getStatusField(nth).invoke('text')
},
- clickStatus(nth) {
- this.getStatusField(nth).click()
- },
getTableHead() {
- return cy.getByDataTestId('manuscripts-header-row')
+ return cy.get('.ant-table-thead')
},
getArticleTitleByRow(nth) {
return cy.get(ARTICLE_TITLE).eq(nth)
@@ -151,18 +156,17 @@ export const ManuscriptsPage = {
return cy.get(ARTICLE_ID).eq(nth)
},
clickArticleId() {
- return this.getArticleIdByRow(0).click()
+ return this.getArticleIdByRow(0).scrollIntoView().click()
},
- clickTableHead(nth) {
- this.getTableHead(nth).click()
+ filterColumnByValue(columnKey, valueLabel) {
+ cy.get(`.ant-table-thead [data-testid="${columnKey}"]`)
+ .find('.ant-table-filter-trigger')
+ .click()
+ cy.get('.ant-table-filter-dropdown').contains(valueLabel).click()
+ cy.get('.ant-table-filter-dropdown').contains('button', 'OK').click()
},
selectCustomStatus(statusLabel) {
- cy.get(
- '[data-testid=manuscripts-header-row] [data-testid="submission.$customStatus"]',
- )
- // .scrollIntoView()
- .click()
- cy.get('[data-testid="select-option"]').contains(statusLabel).click()
+ this.filterColumnByValue('submission.$customStatus', statusLabel)
},
getArticleLabel() {
return cy.get(ARTICLE_LABEL)
@@ -170,6 +174,12 @@ export const ManuscriptsPage = {
clickArticleLabel(nth) {
this.getArticleLabel().eq(nth).click()
},
+ clickArticleLabelClear(nth) {
+ this.getArticleLabel()
+ .eq(nth)
+ .find('.ant-select-clear')
+ .click({ force: true })
+ },
getAllArticleTopics() {
return cy.get(ARTICLE_TOPIC)
},
@@ -211,7 +221,7 @@ export const ManuscriptsPage = {
return cy.getByContainsClass(TABLE_CELL).eq(1)
},
getLabelRow(nth) {
- return cy.get(LABEL).eq(nth)
+ return cy.get(ARTICLE_LABEL).eq(nth)
},
getTableHeader() {
return cy.get(TABLE_HEADER, { timeout: 15000 })
@@ -234,38 +244,32 @@ export const ManuscriptsPage = {
getSelectedArticlesCount() {
return cy.getByDataTestId('selected-manuscripts-number').invoke('text')
},
- getActionDropdown() {
- return cy.getByDataTestId('manuscripts-dropdown-container').click()
- },
clickDelete() {
- this.getActionDropdown().contains('Archive').click()
+ cy.contains('button', /^Archive$/).click()
},
getConfirmButton() {
- return cy.get(CONFIRM_BUTTON)
- },
- getLabelDropdown() {
- return cy.get(DROPDOWN_LABEL).eq(0)
+ return cy.contains('button', 'OK')
},
clickConfirm() {
- this.getConfirmButton().click()
+ this.getConfirmButton().should('be.visible').click()
},
getConfirmationMessageForBulkDelete() {
return cy.get(CONFIRMATION_MESSAGE)
},
getCloseButton() {
- return cy.get(BUTTON).contains('Cancel')
+ return cy.contains('button', 'Cancel')
},
clickClose() {
- this.getCloseButton().click()
+ this.getCloseButton().should('be.visible').click()
},
getEditorName() {
return cy.getByContainsClass(EDITOR_NAME_CELL)
},
getTooltipIcon() {
- return cy.getByDataTestId('info-icon')
+ return cy.getByDataTestId('abstract-tooltip-icon')
},
getTooltipText() {
- return cy.getByContainsClass(TOOLTIP_TEXT)
+ return cy.getByDataTestId('abstract-tooltip')
},
getNumberOfAvailableArticles() {
return cy.get(ARTICLES_COUNT).eq(-1)
@@ -276,12 +280,6 @@ export const ManuscriptsPage = {
clickPaginationButton(nth) {
this.getPaginationButton(nth).click({ force: true })
},
- getSelectButton() {
- return cy.get(BUTTON).contains('Select')
- },
- clickSelect() {
- this.getSelectButton().click()
- },
getSuccessfulImportPopup() {
return cy.get(IMPORT_CONFIRMATION_POPUP, { timeout: 600000 })
},
diff --git a/docker-compose.yml b/docker-compose.yml
index 74d67882c..cba8530d2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -144,6 +144,8 @@ services:
- ./packages/server/utils:/home/node/app/utils
- ./packages/server/profiles:/home/node/app/profiles
- ./packages/server/vitest.config.ts:/home/node/app/vitest.config.ts
+ - ./packages/server/vitest.setup.ts:/home/node/app/vitest.setup.ts
+ - ./packages/server/vitest.workerDb.ts:/home/node/app/vitest.workerDb.ts
healthcheck:
test: ['CMD', '/bin/sh', '/home/node/app/scripts/server_healthy.sh']
interval: 1s
diff --git a/packages/client/app/components/component-chat/src/EllipsisDropdown.jsx b/packages/client/app/components/component-chat/src/EllipsisDropdown.jsx
index 9e3fe61ac..65103895a 100644
--- a/packages/client/app/components/component-chat/src/EllipsisDropdown.jsx
+++ b/packages/client/app/components/component-chat/src/EllipsisDropdown.jsx
@@ -41,9 +41,14 @@ const EllipsisDropdown = ({
}
}
- window.addEventListener('click', handleClickOutside)
+ // Deferred so the click that opened the dropdown (still bubbling to
+ // window at mount time) doesn't immediately close it again.
+ const timeoutId = setTimeout(() => {
+ window.addEventListener('click', handleClickOutside)
+ }, 0)
return () => {
+ clearTimeout(timeoutId)
window.removeEventListener('click', handleClickOutside)
}
}, [show])
diff --git a/packages/client/app/components/component-chat/src/MessageContainer.jsx b/packages/client/app/components/component-chat/src/MessageContainer.jsx
index f7df9c365..86adec55f 100644
--- a/packages/client/app/components/component-chat/src/MessageContainer.jsx
+++ b/packages/client/app/components/component-chat/src/MessageContainer.jsx
@@ -16,7 +16,7 @@ const MessageContainer = styled.section`
background: rgb(255 255 255);
display: flex;
flex-direction: column;
- height: 100vh;
+ height: 100%;
${props =>
props.$channels
diff --git a/packages/client/app/components/component-chat/src/Messages/style.jsx b/packages/client/app/components/component-chat/src/Messages/style.jsx
index 45d913b13..7d745bc4f 100644
--- a/packages/client/app/components/component-chat/src/Messages/style.jsx
+++ b/packages/client/app/components/component-chat/src/Messages/style.jsx
@@ -217,7 +217,7 @@ export const UnreadLabel = styled(ChatLabel)`
export const DateLabelContainer = styled(ChatLabelContainer)`
border-top: 2px solid #6c6c6c;
- margin: 40px 0 30px;
+ margin: ${grid(5)} ${grid(2)};
`
export const DateLabel = styled(ChatLabel)`
background-color: #fff;
diff --git a/packages/client/app/components/component-cms-manager/src/collection/CollectionList.jsx b/packages/client/app/components/component-cms-manager/src/collection/CollectionList.jsx
index 38f4c30b3..310e69394 100644
--- a/packages/client/app/components/component-cms-manager/src/collection/CollectionList.jsx
+++ b/packages/client/app/components/component-cms-manager/src/collection/CollectionList.jsx
@@ -14,9 +14,9 @@ import {
ActionButton,
PaddedContent,
SectionContent,
- LabelBadge,
} from '../../../shared'
import Page from '../../../../ui/shared/Page'
+import Badge from '../../../../ui/shared/Badge'
import CollectionModalForm from './CollectionModalForm'
const StyledContent = styled.div`
@@ -184,9 +184,9 @@ const CollectionList = ({
component: ({ collection }) => {
return collection && collection.active ? (
- True
+ True
) : (
- False
+ False
)
},
},
diff --git a/packages/client/app/components/component-config-manager/src/ConfigManagerForm.jsx b/packages/client/app/components/component-config-manager/src/ConfigManagerForm.jsx
index 069d3c47b..e76f746a9 100644
--- a/packages/client/app/components/component-config-manager/src/ConfigManagerForm.jsx
+++ b/packages/client/app/components/component-config-manager/src/ConfigManagerForm.jsx
@@ -24,7 +24,6 @@ import emailTemplatesToSchema from './helpers'
import { EmailTemplatesProvider } from '../../component-email-templates/hooks/EmailTemplatesContext'
import NotificationPage from '../../component-notification-event/NotificationPage'
import { T } from '../../component-notification-event/misc/constants'
-import { getFormBadgeBg } from '../../component-email-templates/src/handlebarsAutocomplete/helpers'
import DescriptionField from './ui/DescriptionField'
const StyledContainer = styled.div`
@@ -105,8 +104,9 @@ const EmailsTabWrapper = styled(StyledSectionContent)`
padding: ${grid(2)} ${grid(4)};
span.handlebars {
- background-color: ${getFormBadgeBg('common')};
- border-radius: 5px;
+ background-color: ${th('colorSecondary')};
+ color: ${th('colorTextReverse')};
+ border-radius: 3px;
box-shadow:
0 0 6px 0 #0001,
inset 0 0 4px 0 #0002;
@@ -114,22 +114,6 @@ const EmailsTabWrapper = styled(StyledSectionContent)`
padding: 2px 4px;
text-rendering: geometricprecision;
}
-
- span.handlebars.submission-form {
- background-color: ${getFormBadgeBg('submission')};
- }
-
- span.handlebars.review-form {
- background-color: ${getFormBadgeBg('review')};
- }
-
- span.handlebars.decision-form {
- background-color: ${getFormBadgeBg('decision')};
- }
-
- span.handlebars.editors-form {
- background-color: ${getFormBadgeBg('editors')};
- }
}
.wax-surface-scroll {
diff --git a/packages/client/app/components/component-dashboard/src/components/DashboardEditsPage.jsx b/packages/client/app/components/component-dashboard/src/components/DashboardEditsPage.jsx
index 8da161414..fe7b37564 100644
--- a/packages/client/app/components/component-dashboard/src/components/DashboardEditsPage.jsx
+++ b/packages/client/app/components/component-dashboard/src/components/DashboardEditsPage.jsx
@@ -1,118 +1,23 @@
/* eslint-disable react-hooks/exhaustive-deps */
-import { useMutation, useQuery } from '@apollo/client/react'
-import { useEffect, useContext } from 'react'
-import { useLocation } from 'react-router-dom'
+import { useMutation } from '@apollo/client/react'
+import { useEffect } from 'react'
-import { ConfigContext } from '../../../config/src'
-import { useCurrentUser } from '../../../../pages/hooks/useCurrentUser'
-import {
- extractFilters,
- extractSortData,
- URI_PAGENUM_PARAM,
- useQueryParams,
-} from '../../../../shared/urlParamUtils'
-import {
- UPDATE_TAB,
- REMOVE_TASK_ALERTS_FOR_CURRENT_USER,
- DASHBOARD,
- UPDATE_MANUSCRIPT,
-} from '../../../../queries'
+import { UPDATE_TAB } from '../../../../queries'
import EditorTable from './sections/EditorTable'
-import { CommsErrorBanner, Spinner } from '../../../shared'
const DashboardEditsPage = () => {
- const location = useLocation()
- const config = useContext(ConfigContext)
- const wantedRoles = ['seniorEditor', 'handlingEditor', 'editor']
-
- const currentUser = useCurrentUser()
-
- const applyQueryParams = useQueryParams()
-
- const uriQueryParams = new URLSearchParams(location.search)
- const page = uriQueryParams.get(URI_PAGENUM_PARAM) || 1
- const sortName = extractSortData(uriQueryParams).name
- const sortDirection = extractSortData(uriQueryParams).direction
- const filters = extractFilters(uriQueryParams)
-
- const limit = config?.manuscript?.paginationCount || 10
-
- const { data, loading, error } = useQuery(DASHBOARD, {
- variables: {
- wantedRoles,
- sort: sortName
- ? { field: sortName, isAscending: sortDirection === 'ASC' }
- : null,
- offset: (page - 1) * limit,
- limit,
- filters,
- timezoneOffsetMinutes: new Date().getTimezoneOffset(),
- groupId: config.groupId,
- searchInAllVersions: false,
- },
- fetchPolicy: 'network-only',
- })
-
const [updateTab] = useMutation(UPDATE_TAB)
- const [update] = useMutation(UPDATE_MANUSCRIPT)
- const [doUpdateManuscript] = useMutation(UPDATE_MANUSCRIPT)
-
- const setReadyToEvaluateLabels = id => {
- update({
- variables: {
- id,
- input: JSON.stringify({
- submission: {
- $customStatus: 'readyToEvaluate',
- },
- }),
- },
- })
- }
-
- const unsetCustomStatus = id => {
- update({
- variables: {
- id,
- input: JSON.stringify({
- submission: {
- $customStatus: null,
- },
- }),
- },
- })
- }
-
- const [removeTaskAlertsForCurrentUser] = useMutation(
- REMOVE_TASK_ALERTS_FOR_CURRENT_USER,
- )
-
useEffect(() => {
updateTab({
variables: {
tab: 'edits',
},
})
- removeTaskAlertsForCurrentUser()
}, [])
- if (loading) return
- if (error) return
-
- return (
-
- )
+ return
}
export default DashboardEditsPage
diff --git a/packages/client/app/components/component-dashboard/src/components/DashboardLayout.jsx b/packages/client/app/components/component-dashboard/src/components/DashboardLayout.jsx
index 8cd886172..7ea7838ab 100644
--- a/packages/client/app/components/component-dashboard/src/components/DashboardLayout.jsx
+++ b/packages/client/app/components/component-dashboard/src/components/DashboardLayout.jsx
@@ -9,13 +9,7 @@ import { useTranslation } from 'react-i18next'
import { Button } from '../../../pubsweet'
import { HiddenTabsContainer, Tab, TabContainer } from '../../../shared'
import Page from '../../../../ui/shared/Page'
-import SearchControl from '../../../component-manuscripts/src/SearchControl'
import { ControlsContainer } from '../../../component-manuscripts/src/style'
-import {
- URI_PAGENUM_PARAM,
- URI_SEARCH_PARAM,
- useQueryParams,
-} from '../../../../shared/urlParamUtils'
import { FlexRow } from '../../../../globals'
import { ConfigContext } from '../../../config/src'
@@ -43,9 +37,6 @@ const DashboardLayout = ({ children }) => {
const navigate = useNavigate()
const location = useLocation()
const { groupName } = useParams()
- const applyQueryParams = useQueryParams()
- const uriQueryParams = new URLSearchParams(location.search)
- const currentSearchQuery = uriQueryParams.get(URI_SEARCH_PARAM)
const dashboardPages = []
const { t } = useTranslation()
@@ -85,15 +76,6 @@ const DashboardLayout = ({ children }) => {
))}
-
- applyQueryParams({
- [URI_SEARCH_PARAM]: newQuery,
- [URI_PAGENUM_PARAM]: 1,
- })
- }
- currentSearchQuery={currentSearchQuery}
- />