diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index bc1e44c06a..ee3d340079 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -75,7 +75,7 @@ jobs: matrix: #IMPORTANT: must, must, must match the total number of containers below: runSubsetOfCypressTests.sh.sh -t # container: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ] - container: [ 1, 2, 3, 4, 5, 6] + container: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] services: postgres: @@ -140,7 +140,7 @@ jobs: - name: Run Cypress tests run: | cd e2e-tests - ../.github/scripts/runSubsetOfCypressTests.sh -t 6 -c ${{ matrix.container }} -f 'projects_crud|/skills_table_spec|/skill_reuse_spec|quiz_creation|question_def|metrics-reUsedData_spec|quiz_and_survey|quiz_runs|quiz_skill_assignment|quiz_read|quiz_role|quiz_settings|quiz_skills-in_project_reuse|client-display_quiz_spec|client-display_quiz_theme_spec|client-display_quiz_visual_spec|client-display_run_quiz_spec|run_survey_spec|quiz_skills-catalog_spec|/inception|user_actions|configure-skill-expiration_spec|skill-expiration-table_spec|configure_video_spec|configure_video_features_spec|configure_skill_video_self_report_spec|configure_video_validation_spec|handle_video_without_duration_spec|client_display_video_on_subject_page_spec|client_display_video_on_skill_page_spec|/skills_spec|/users_spec|/subjects_spec|/levels_management_spec|/skills_group_spec|/skills_group_modal_spec|/move-skills/|/badges_spec|/skill-reuse/skill_reuse/|/catalog/|/project_settings_spec|/icon_manager_spec|/not_found_spec|my-usage_spec|/error_pages_spec|/add_skills_to_badge_spec|/tag-skills|/settings_spec|/client-display/|/learning-path/|/copy_project_spec|/project_errors_spec|/selfReport-approvalHistory_spec|/approver|/manage-my-projects_spec|/accessibility|/community/|/metrics/projectMetrics|/metrics/skillMetrics_spec|/metrics/subjectMetrics_spec|/projects_invite_only_spec|/app_features_spec|/breadcrumb_spec|/contact|/cross-project_spec|/discoverable_proj_invite_spec|/login_spec|/markdown_spec/metrics/multipleProjectMetrics_empty_spec|/metrics/multipleProjectMetrics_spec|/my-progress_breadcrumb_spec|/my-progress_spec|/my-progress-badges_spec|/navigation_spec|/progress_and_ranking_disabled_spec|/project_expiration_spec|performedSkills_table_spec' + ../.github/scripts/runSubsetOfCypressTests.sh -t 10 -c ${{ matrix.container }} -f 'projects_crud|/skills_table_spec|/skill_reuse_spec|quiz_creation|question_def|metrics-reUsedData_spec|quiz_and_survey|quiz_runs|quiz_skill_assignment|quiz_read|quiz_role|quiz_settings|quiz_skills-in_project_reuse|client-display_quiz_spec|client-display_quiz_theme_spec|client-display_quiz_visual_spec|client-display_run_quiz_spec|run_survey_spec|quiz_skills-catalog_spec|/inception|user_actions|configure-skill-expiration_spec|skill-expiration-table_spec|configure_video_spec|configure_video_features_spec|configure_skill_video_self_report_spec|configure_video_validation_spec|handle_video_without_duration_spec|client_display_video_on_subject_page_spec|client_display_video_on_skill_page_spec|/skills_spec|/users_spec|/subjects_spec|/levels_management_spec|/skills_group_spec|/skills_group_modal_spec|/move-skills/|/badges_spec|/skill-reuse/skill_reuse/|/catalog/|/project_settings_spec|/icon_manager_spec|/not_found_spec|my-usage_spec|/error_pages_spec|/add_skills_to_badge_spec|/tag-skills|/settings_spec|/client-display/|/learning-path/|/copy_project_spec|/project_errors_spec|/selfReport-approvalHistory_spec|/approver|/manage-my-projects_spec|/accessibility|/community/|/metrics/projectMetrics|/metrics/skillMetrics_spec|/metrics/subjectMetrics_spec|/projects_invite_only_spec|/app_features_spec|/breadcrumb_spec|/contact|/cross-project_spec|/discoverable_proj_invite_spec|/login_spec|/markdown_spec/metrics/multipleProjectMetrics_empty_spec|/metrics/multipleProjectMetrics_spec|/my-progress_breadcrumb_spec|/my-progress_spec|/my-progress-badges_spec|/navigation_spec|/progress_and_ranking_disabled_spec|/project_expiration_spec|performedSkills_table_spec|/projects_admin_management_spec|/projects_modal_management_spec|/projects_modal_validation_spec|/projects_spec' cd .. env: ELECTRON_EXTRA_LAUNCH_ARGS: '--disable-gpu' diff --git a/dashboard-prime/src/components/access/AccessSettings.vue b/dashboard-prime/src/components/access/AccessSettings.vue index c97ce7c518..2dc2f3ea95 100644 --- a/dashboard-prime/src/components/access/AccessSettings.vue +++ b/dashboard-prime/src/components/access/AccessSettings.vue @@ -1,12 +1,17 @@ + + + + \ No newline at end of file diff --git a/dashboard-prime/src/components/levels/NewLevel.vue b/dashboard-prime/src/components/levels/NewLevel.vue index 03d88c1078..f85e7a24bf 100644 --- a/dashboard-prime/src/components/levels/NewLevel.vue +++ b/dashboard-prime/src/components/levels/NewLevel.vue @@ -73,6 +73,10 @@ const initialLevelData = { points: props.level.points, }; +if (!props.isEdit) { + initialLevelData.percent = props.allLevels.reduce((max, level) => Math.max(max, level.percent), 0) +1; +} + const boundsValidator = (value) => { const gte = (value, compareTo) => value >= compareTo; const lte = (value, compareTo) => value <= compareTo; diff --git a/dashboard-prime/src/components/projects/EditProject.vue b/dashboard-prime/src/components/projects/EditProject.vue index 3c5486d8e4..ada5453920 100644 --- a/dashboard-prime/src/components/projects/EditProject.vue +++ b/dashboard-prime/src/components/projects/EditProject.vue @@ -103,7 +103,7 @@ const schema = object({ .max(appConfig.maxProjectNameLength) .nullValueNotAllowed() .test('uniqueName', 'Project Name already exists', (value) => checkProjNameUnique(value)) - .customNameValidator() + .customNameValidator('Project Name') .label('Project Name'), 'projectId': string() .required() diff --git a/dashboard-prime/src/components/projects/MyProject.vue b/dashboard-prime/src/components/projects/MyProject.vue index 3248344cc0..d74248e16b 100644 --- a/dashboard-prime/src/components/projects/MyProject.vue +++ b/dashboard-prime/src/components/projects/MyProject.vue @@ -28,7 +28,7 @@ const announcer = useSkillsAnnouncer() // data items const pinned = ref(false); -const projectInternal = ref({ ...props.project }); +const projectInternal = computed(() => props.project ); const stats = ref([]); const showEditProjectModal = ref(false); const showCopyProjectModal = ref(false); @@ -247,6 +247,7 @@ defineExpose({ {{ warningMsgAboutPoints}}
{ provide('createOrUpdateProject', openProjectModal) const projectAdded = (project) => { + const existingIndex = projects.value.findIndex((item) => item.projectId === project.originalProjectId) if (existingIndex >= 0) { + console.log(`edit: ${existingIndex} project at this indeex`) projects.value.splice(existingIndex, 1, project) + announcer.polite(`Project ${project.name} has been updated`); } else { projects.value.push(project) SkillsReporter.reportSkill('CreateProject'); + announcer.polite(`Project ${project.name} has been created`); } - announcer.polite(`Project ${project.name} has been created`); -}; -const projectEdited = (editedProject) => { - // ProjectService.saveProject(editedProject).then(() => { - loadProjects().then(() => { - // this.$refs.projectsTable.focusOnEditButton(editedProject.projectId); - nextTick(() => { - announcer.polite(`Project ${editedProject.name} has been edited`); - }); - }); - // }); }; const enableDropAndDrop = () => { if (projects.value && projects.value.length > 0 && projects.value.length < appConfig.numProjectsForTableView) { @@ -211,12 +204,9 @@ const saveProject = (values, isEdit, projectId) => { } return ProjectService.getProject(projRes.projectId) .then((retrievedProj) => { - if (!isEdit) { - projectAdded(retrievedProj); - } else { - projectEdited(retrievedProj); - } - return {...retrievedProj, originalProjectId: projectId} + const projWithOriginalId = { ...retrievedProj, originalProjectId: projectId } + projectAdded(projWithOriginalId) + return projWithOriginalId }) }) } @@ -276,12 +266,14 @@ const hasData = computed(() => {
-
-
-
Updating sort order!
- -
+
+
{
- + diff --git a/e2e-tests/cypress/e2e/client-display/client-display_spec.js b/e2e-tests/cypress/e2e/client-display/client-display_spec.js index e67ca22212..81333d0a01 100644 --- a/e2e-tests/cypress/e2e/client-display/client-display_spec.js +++ b/e2e-tests/cypress/e2e/client-display/client-display_spec.js @@ -217,27 +217,39 @@ describe('Client Display Tests', () => { it('clearly represent navigable components', () => { cy.cdVisit('?internalBackButton=true', true); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSubj(0, 'Subject 1',true); + cy.get('[data-cy="pointHistoryChartWithData"]') // make sure it can navigate into each skill via title cy.cdClickSkill(0, false); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(1, false); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(2, false); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(3, false); + cy.get('[data-cy="prerequisitesCard"] [data-cy="skillLink-proj1-skill2"]') cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') // make sure it can navigate into each skill via progress bar cy.cdClickSkill(0); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(1); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(2); cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') cy.cdClickSkill(3); + cy.get('[data-cy="prerequisitesCard"] [data-cy="skillLink-proj1-skill2"]') cy.cdBack('Subject 1'); + cy.get('[data-cy="pointHistoryChartWithData"]') }); it('components should not be clickable in the summary only option', () => { diff --git a/e2e-tests/cypress/e2e/projects_admin_management_spec.js b/e2e-tests/cypress/e2e/projects_admin_management_spec.js index 9e004a14ca..cdb0f77282 100644 --- a/e2e-tests/cypress/e2e/projects_admin_management_spec.js +++ b/e2e-tests/cypress/e2e/projects_admin_management_spec.js @@ -137,7 +137,7 @@ describe('Projects Admin Management Tests', () => { .contains('Failed to add User Role'); }); - it.skip('Add Admin No Query', () => { + it('Add Admin No Query', () => { cy.request('POST', '/app/projects/proj1', { projectId: 'proj1', name: 'proj1' @@ -157,13 +157,12 @@ describe('Projects Admin Management Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProject'); - cy.get('[data-cy="existingUserInput"]') - .type('{enter}'); + cy.get('[data-cy="existingUserInputDropdown"] [data-pc-name="dropdownbutton"]').click() cy.wait('@suggest'); cy.wait(500); - cy.contains('root@skills.org') - .click(); - cy.get('[data-cy="userRoleSelector"]') .select('Administrator'); + cy.get('#existingUserInput_0').contains('root@skills.org').click(); + cy.get('[data-cy="userRoleSelector"]').click() + cy.get('[data-pc-section="panel"] [aria-label="Administrator"]').click(); cy.get('[data-cy="addUserBtn"]').click(); cy.wait('@addAdmin'); @@ -205,7 +204,7 @@ describe('Projects Admin Management Tests', () => { } }); - it.skip('Add and Remove Admin', () => { + it('Add and Remove Admin', () => { cy.request('POST', '/app/projects/proj1', { projectId: 'proj1', name: 'proj1' @@ -229,9 +228,9 @@ describe('Projects Admin Management Tests', () => { .type('root'); cy.wait('@suggest'); cy.wait(500); - cy.get('.vs__dropdown-option').contains('root@skills.org') - .click(); - cy.get('[data-cy="userRoleSelector"]') .select('Administrator'); + cy.get('#existingUserInput_0').contains('root').click(); + cy.get('[data-cy="userRoleSelector"]').click() + cy.get('[data-pc-section="panel"] [aria-label="Administrator"]').click(); cy.get('[data-cy="addUserBtn"]').click(); cy.wait('@addAdmin'); @@ -254,7 +253,7 @@ describe('Projects Admin Management Tests', () => { .as('cyRows1'); }); - it.skip('Add Admin - forward slash character does not cause error', () => { + it('Add Admin - forward slash character does not cause error', () => { cy.request('POST', '/app/projects/proj1', { projectId: 'proj1', name: 'proj1' @@ -280,7 +279,7 @@ describe('Projects Admin Management Tests', () => { cy.wait('@suggest'); }); - it.skip('Add Approver role then upgrade to Admin', () => { + it('Add Approver role then upgrade to Admin', () => { cy.request('POST', '/app/projects/proj1', { projectId: 'proj1', name: 'proj1' @@ -306,9 +305,9 @@ describe('Projects Admin Management Tests', () => { .type('root'); cy.wait('@suggest'); cy.wait(500); - cy.get('.vs__dropdown-menu').contains('root@skills.org') - .click(); - cy.get('[data-cy="userRoleSelector"]').select('Approver'); + cy.get('#existingUserInput_0').contains('root').click(); + cy.get('[data-cy="userRoleSelector"]').click() + cy.get('[data-pc-section="panel"] [aria-label="Approver"]').click(); cy.get('[data-cy="addUserBtn"]').click(); cy.wait('@addApprover'); @@ -332,15 +331,17 @@ describe('Projects Admin Management Tests', () => { ], 5, true, null, false); cy.get(`${tableSelector} [data-cy="controlsCell_root@skills.org"] [data-cy="editUserBtn"]`).click(); - cy.get('[data-cy="roleDropDown_root@skills.org"]').select('Administrator'); + cy.get('[data-cy="roleDropDown_root@skills.org"]').click() + cy.get('[data-pc-section="panel"] [data-pc-section="itemlabel"]').contains('Administrator').click(); cy.wait('@addAdmin') + cy.get(`${tableSelector} thead th`).contains('User').click(); cy.validateTable(tableSelector, [ - [{ colIndex: 0, value: expectedUserName }, { colIndex: 1, value: 'Administrator' }], [{ colIndex: 0, value: 'root@' }, { colIndex: 1, value: 'Administrator' }], + [{ colIndex: 0, value: expectedUserName }, { colIndex: 1, value: 'Administrator' }], ], 5, true, null, false); }); - it.skip('Existing projects are not suggested', () => { + it('Existing users are not suggested', () => { cy.register('newuser', 'password', false, 'some display name') cy.fixture('vars.json').then((vars) => { cy.logout() @@ -370,17 +371,21 @@ describe('Projects Admin Management Tests', () => { cy.get('[data-cy="existingUserInput"]').type('some'); cy.wait('@suggest'); cy.wait(500); - cy.get('.vs__dropdown-menu').contains('some display name') + cy.get('[data-pc-section="list"] [data-pc-section="item"]').should('have.length', 1) + cy.get('[data-pc-section="list"]').contains('some display name') .click(); - cy.get('[data-cy="userRoleSelector"]').select('Approver'); + cy.get('[data-cy="userRoleSelector"]').click() + cy.get('[data-pc-section="panel"] [aria-label="Approver"]').click(); cy.get('[data-cy="addUserBtn"]').click(); + + cy.wait('@addApprover'); cy.get('[data-cy="userCell_newuser"]').should("exist"); cy.get('[data-cy="existingUserInput"]').type('some'); cy.wait('@suggest'); cy.wait(1500); - cy.get('.vs__dropdown-menu').contains('some display name').should('not.exist') + cy.get('[data-pc-section="list"] [data-pc-section="item"]').should('have.length', 0) }); }) diff --git a/e2e-tests/cypress/e2e/projects_modal_management_spec.js b/e2e-tests/cypress/e2e/projects_modal_management_spec.js index c216a8c014..7868664298 100644 --- a/e2e-tests/cypress/e2e/projects_modal_management_spec.js +++ b/e2e-tests/cypress/e2e/projects_modal_management_spec.js @@ -49,7 +49,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=deleteProjBtn]') .eq(0) .click(); - cy.get('[data-cy=closeRemovalSafetyCheck]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.wait(200); cy.get('[data-cy=deleteProjBtn]') @@ -67,7 +67,7 @@ describe('Projects Modal Management Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); cy.get('[data-cy="inception-button"]').contains('Level'); - cy.get('[data-cy="noContent"]').contains('No Projects Yet'); + cy.get('[data-cy="noProjectsYet"]').contains('No Projects Yet'); cy.get('[data-cy=newProjectButton]').should('be.enabled') cy.get('[data-cy=newProjectButton]') .focus() @@ -76,7 +76,7 @@ describe('Projects Modal Management Tests', () => { .should('have.value', ''); cy.get('[data-cy="projectNameError"]') .should('have.value', ''); - cy.get('[data-cy=closeProjectButton]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy="projectName"]') .should('not.exist'); @@ -96,7 +96,7 @@ describe('Projects Modal Management Tests', () => { cy.wait('@loadProjects'); cy.get('[data-cy="inception-button"]').contains('Level'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click(); cy.get('[data-cy="projectName"]') .type('test'); cy.get('[data-cy="projectName"]') @@ -114,7 +114,7 @@ describe('Projects Modal Management Tests', () => { .should('have.value', 'test'); cy.get('[data-cy="projectNameError"]') .should('have.value', ''); - cy.get('[data-cy=closeProjectButton]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.contains('test'); }); @@ -133,8 +133,8 @@ describe('Projects Modal Management Tests', () => { cy.wait('@loadProjects'); cy.get('[data-cy="inception-button"]').contains('Level'); - cy.clickButton('Project'); - cy.get('[data-cy=closeProjectButton]') + cy.get('[data-cy="newProjectButton"]').click() + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy="projectName"]') .should('not.exist'); @@ -157,7 +157,7 @@ describe('Projects Modal Management Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); cy.get('[data-cy="inception-button"]').contains('Level'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type(providedName); cy.wait('@projectExists'); @@ -179,14 +179,13 @@ describe('Projects Modal Management Tests', () => { cy.wait('@loadProjects'); cy.get('[data-cy="inception-button"]').contains('Level'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type('InitValue'); cy.getIdField() .should('have.value', 'InitValue'); - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="enableIdInput"] input').click(); cy.get('[data-cy="projectName"]') .type('MoreValue'); @@ -212,7 +211,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=newProjectButton]') .click(); - cy.get('[data-cy=closeProjectButton]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy=newProjectButton]') .should('have.focus'); @@ -221,14 +220,15 @@ describe('Projects Modal Management Tests', () => { .click(); cy.get('[data-cy=projectName]') .type('test 123'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .click(); cy.get('[data-cy=newProjectButton]') .should('have.focus'); cy.get('[data-cy=newProjectButton]') .click(); - cy.get('[aria-label=Close]') + cy.get('[data-cy="projectName"]') + cy.get('[data-pc-group-section="headericon"][data-pc-section="closebutton"]') .click(); cy.get('[data-cy=newProjectButton]') .should('have.focus'); @@ -249,31 +249,31 @@ describe('Projects Modal Management Tests', () => { cy.get(proj1EditBtn) .click(); - cy.get('.modal-body [data-cy=projectName]').should('be.visible'); + cy.get('[data-cy=projectName]').should('be.visible'); cy.wait(250); cy.realPress('Escape'); - cy.get('.modal-body [data-cy=projectName]').should('not.exist'); + cy.get('[data-cy=projectName]').should('not.exist'); cy.wait(600) cy.get(proj1EditBtn).should('have.focus'); cy.get(proj1EditBtn).click(); - cy.get('.modal-body [data-cy=projectName]').should('be.visible'); - cy.get('.modal-footer [data-cy=closeProjectButton]').click(); - cy.get('.modal-body [data-cy=projectName]').should('not.exist'); + cy.get('[data-cy=projectName]').should('be.visible'); + cy.get('[data-cy=closeDialogBtn]').click(); + cy.get('[data-cy=projectName]').should('not.exist'); cy.wait(600) cy.get(proj1EditBtn).should('have.focus'); cy.get(proj1EditBtn).click(); - cy.get('.modal-body [data-cy=projectName]').type('test 123'); - cy.get('.modal-footer [data-cy=saveProjectButton]').click(); - cy.get('.modal-body [data-cy=projectName]').should('not.exist'); + cy.get('[data-cy=projectName]').type('test 123'); + cy.get('[data-cy=saveDialogBtn]').click(); + cy.get('[data-cy=projectName]').should('not.exist'); cy.wait(600) cy.get(proj1EditBtn).should('have.focus'); cy.get(proj1EditBtn).click(); - cy.get('.modal-body [data-cy=projectName]').should('be.visible'); - cy.get('.modal-header [aria-label=Close]').click(); - cy.get('.modal-body [data-cy=projectName]').should('not.exist'); + cy.get('[data-cy=projectName]').should('be.visible'); + cy.get('[data-pc-group-section="headericon"][data-pc-section="closebutton"]').click() + cy.get('[data-cy=projectName]').should('not.exist'); cy.wait(600) cy.get(proj1EditBtn).should('have.focus'); }); @@ -302,7 +302,7 @@ describe('Projects Modal Management Tests', () => { .click(); cy.get('[data-cy=addLevel]') .click(); - cy.get('[data-cy=cancelLevel]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy=addLevel]') .should('have.focus'); @@ -313,8 +313,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=addLevel]') .click(); - cy.get('[aria-label=Close]') - .filter('.text-light') + cy.get('[data-pc-section="closebuttonicon"]') .click(); cy.get('[data-cy=addLevel]') .should('have.focus'); @@ -322,7 +321,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=editLevelButton]') .eq(0) .click(); - cy.get('[data-cy=cancelLevel]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy=editLevelButton]') .eq(0) @@ -335,8 +334,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=editLevelButton]') .eq(0) .click(); - cy.get('[aria-label=Close]') - .filter('.text-light') + cy.get('[data-pc-section="closebuttonicon"]') .click(); cy.get('[data-cy=editLevelButton]') .eq(0) @@ -352,7 +350,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=editLevelButton]') .eq(3) .click(); - cy.get('[data-cy=cancelLevel]') + cy.get('[data-cy=closeDialogBtn]') .click(); cy.get('[data-cy=editLevelButton]') .eq(3) @@ -365,8 +363,7 @@ describe('Projects Modal Management Tests', () => { cy.get('[data-cy=editLevelButton]') .eq(3) .click(); - cy.get('[aria-label=Close]') - .filter('.text-light') + cy.get('[data-pc-section="closebuttonicon"]') .click(); cy.get('[data-cy=editLevelButton]') .eq(3) diff --git a/e2e-tests/cypress/e2e/projects_modal_validation_spec.js b/e2e-tests/cypress/e2e/projects_modal_validation_spec.js index 5a79b7bb33..4ec85a6148 100644 --- a/e2e-tests/cypress/e2e/projects_modal_validation_spec.js +++ b/e2e-tests/cypress/e2e/projects_modal_validation_spec.js @@ -44,13 +44,13 @@ describe('Projects Modal Validation Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type('My New test Project'); cy.get('[data-cy=projectNameError]') - .contains('The value for the Project Name is already taken') + .contains('Project Name already exists') .should('be.visible'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .should('be.disabled'); }); @@ -67,19 +67,18 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type('Other Project Name'); - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="enableIdInput"] input').click(); cy.getIdField() .clear() .type('MyNewtestProject'); cy.get('[data-cy=idError]') - .contains('The value for the Project ID is already taken') + .contains('Project ID already exists') .should('be.visible'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .should('be.disabled'); }); @@ -98,7 +97,7 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type(providedName); cy.getIdField() @@ -107,15 +106,15 @@ describe('Projects Modal Validation Tests', () => { cy.clickSave(); cy.wait('@postNewProject'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type(providedName.toLowerCase()); cy.get('[data-cy=projectNameError') - .contains('The value for the Project Name is already taken') + .contains('Project Name already exists') .should('be.visible'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .should('be.disabled'); }); @@ -128,13 +127,13 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="newProjectButton"]').click() + cy.get('[data-cy="enableIdInput"] input') + .click(); cy.getIdField() .type('InitValue'); - cy.get('[data-cy=saveProjectButton') + cy.get('[data-cy=saveDialogBtn') .should('be.disabled'); }); @@ -147,18 +146,18 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() ; cy.get('[data-cy="projectName"]') .type('New Project'); - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="enableIdInput"] input') + .click(); cy.getIdField() .clear(); cy.get('[data-cy=idError]') - .contains('Project ID is required') + .contains('Project ID is a required field') .should('be.visible'); - cy.get('[data-cy=saveProjectButton') + cy.get('[data-cy=saveDialogBtn') .should('be.disabled'); }); @@ -171,34 +170,34 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() cy.get('[data-cy="projectName"]') .type('Great Name'); cy.get('[data-cy="projectNameError"]') .should('not.be.visible'); - cy.get('[data-cy="saveProjectButton"]') + cy.get('[data-cy="saveDialogBtn"]') .should('be.enabled'); cy.get('[data-cy="projectName"]') .type('{selectall}(A) Updated Project Name'); cy.get('[data-cy="projectNameError"]') .contains('Project Name - names may not contain (A)'); - cy.get('[data-cy="saveProjectButton"]') + cy.get('[data-cy="saveDialogBtn"]') .should('be.disabled'); cy.get('[data-cy="projectName"]') .type('{selectall}(B) A Updated Project Name'); cy.get('[data-cy="projectNameError"]') .should('not.be.visible'); - cy.get('[data-cy="saveProjectButton"]') + cy.get('[data-cy="saveDialogBtn"]') .should('be.enabled') }); it('Project name must be > 3 chars < 50 chars', () => { - const minLenMsg = 'Project Name cannot be less than 3 characters.'; - const maxLenMsg = 'Project Name cannot exceed 50 characters.'; + const minLenMsg = 'Project Name must be at least 3 characters'; + const maxLenMsg = 'Project Name must be at most 50 characters'; const projId = 'ProjectId'; cy.intercept('POST', `/app/projects/${projId}`) .as('postNewProject'); @@ -211,10 +210,10 @@ describe('Projects Modal Validation Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="enableIdInput"] input') + .click(); cy.getIdField() .type('ProjectId'); cy.get('[data-cy="projectName"]') @@ -261,9 +260,9 @@ describe('Projects Modal Validation Tests', () => { }); }) .as('loadConfig'); - const minLenMsg = 'Project ID cannot be less than 3 characters.'; - const maxLenMsg = 'Project ID cannot exceed 50 characters.'; - const requiredMsg = 'Project ID is required'; + const minLenMsg = 'Project ID must be at least 3 characters'; + const maxLenMsg = 'Project ID must be at most 50 characters'; + const requiredMsg = 'Project ID is a required field'; const projName = 'Project Name'; const longInvalid = Array(51) @@ -282,10 +281,10 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click() - cy.get('[data-cy="enableIdInput"]') - .click({force: true}); + cy.get('[data-cy="enableIdInput"] input') + .click(); cy.getIdField() .type('12'); @@ -339,7 +338,7 @@ describe('Projects Modal Validation Tests', () => { cy.visit('/administrator/'); cy.get('[data-cy="editProjBtn"]').click() cy.wait('@validateDesc') - cy.get('[data-cy="projectDescriptionError"]').contains('Mocked up validation failure') + cy.get('[data-cy="descriptionError"]').contains('Mocked up validation failure') }); it('null word is not allowed for project ID or project name', () => { @@ -348,12 +347,12 @@ describe('Projects Modal Validation Tests', () => { cy.get('[data-cy="projectName"]') .type('null'); cy.get('[data-cy=projectNameError]') - .contains('Null is not allowed for Project Name') + .contains('Null value is not allowed') .should('be.visible'); cy.get('[data-cy="idError"]') - .contains('Null is not allowed for Project ID') + .contains('Null value is not allowed') .should('be.visible'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .should('be.disabled'); cy.get('[data-cy="projectName"]').clear().type('one') cy.get('[data-cy=projectNameError]').should('not.be.visible') @@ -363,12 +362,12 @@ describe('Projects Modal Validation Tests', () => { cy.get('[data-cy="projectName"]').clear() .type(' NUlL '); cy.get('[data-cy=projectNameError]') - .contains('Null is not allowed for Project Name') + .contains('Null value is not allowed') .should('be.visible'); cy.get('[data-cy="idError"]') - .contains('Null is not allowed for Project ID') + .contains('Null value is not allowed') .should('be.visible'); - cy.get('[data-cy=saveProjectButton]') + cy.get('[data-cy=saveDialogBtn]') .should('be.disabled'); }); diff --git a/e2e-tests/cypress/e2e/projects_sort_spec.js b/e2e-tests/cypress/e2e/projects_sort_spec.js index 7441ad07f0..569270ac23 100644 --- a/e2e-tests/cypress/e2e/projects_sort_spec.js +++ b/e2e-tests/cypress/e2e/projects_sort_spec.js @@ -100,16 +100,12 @@ describe('Projects Sort Order Tests', () => { .dragAndDrop(proj2Card); // overlay over both cards but loading message only on project 1 - cy.get('[data-cy="proj1_overlayShown"] [data-cy="updatingSortMsg"]') - .contains('Updating sort order'); + cy.get('[data-cy="proj1_overlayShown"] [data-cy="overlaySpinner"]') cy.get('[data-cy="proj2_overlayShown"]'); - cy.get('[data-cy="proj2_overlayShown"] [data-cy="updatingSortMsg"]') - .should('not.exist'); + cy.get('[data-cy="proj2_overlayShown"] [data-cy="overlaySpinner"]').should('not.exist'); cy.wait('@proj1Async'); - cy.get('[data-cy="proj1_overlayShown"]') - .should('not.exist'); - cy.get('[data-cy="proj2_overlayShown"]') - .should('not.exist'); + cy.get('[data-cy="proj1_overlayShown"]').should('not.exist'); + cy.get('[data-cy="proj2_overlayShown"]').should('not.exist'); }); it('change sort order using keyboard', () => { @@ -118,19 +114,19 @@ describe('Projects Sort Order Tests', () => { cy.createProject(3); cy.visit('/administrator/'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 1', 'This is project 2', 'This is project 3']); - cy.get('[data-cy="projectCard_proj1"] [data-cy="deleteProjBtn"]') + cy.get('[data-cy="projectCard_proj1"] [data-pc-section="closebutton"]') .tab() .type('{downArrow}'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 2', 'This is project 1', 'This is project 3']); cy.get('[data-cy="projectCard_proj1"] [data-cy="sortControlHandle"]') .should('have.focus'); - cy.get('[data-cy="projectCard_proj1"] [data-cy="deleteProjBtn"]') + cy.get('[data-cy="projectCard_proj1"] [data-pc-section="closebutton"]') .tab() .type('{downArrow}'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 2', 'This is project 3', 'This is project 1']); cy.get('[data-cy="projectCard_proj1"] [data-cy="sortControlHandle"]') .should('have.focus'); - cy.get('[data-cy="projectCard_proj1"] [data-cy="deleteProjBtn"]') + cy.get('[data-cy="projectCard_proj1"] [data-pc-section="closebutton"]') .tab() .type('{downArrow}'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 2', 'This is project 3', 'This is project 1']); @@ -142,13 +138,13 @@ describe('Projects Sort Order Tests', () => { cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 2', 'This is project 3', 'This is project 1']); // now let's move up - cy.get('[data-cy="projectCard_proj3"] [data-cy="deleteProjBtn"]') + cy.get('[data-cy="projectCard_proj3"] [data-pc-section="closebutton"]') .tab() .type('{upArrow}'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 3', 'This is project 2', 'This is project 1']); cy.get('[data-cy="projectCard_proj3"] [data-cy="sortControlHandle"]') .should('have.focus'); - cy.get('[data-cy="projectCard_proj3"] [data-cy="deleteProjBtn"]') + cy.get('[data-cy="projectCard_proj3"] [data-pc-section="closebutton"]') .tab() .type('{upArrow}'); cy.validateElementsOrder('[data-cy="projectCard"]', ['This is project 3', 'This is project 2', 'This is project 1']); diff --git a/e2e-tests/cypress/e2e/projects_spec.js b/e2e-tests/cypress/e2e/projects_spec.js index 0e65673c06..728ed87398 100644 --- a/e2e-tests/cypress/e2e/projects_spec.js +++ b/e2e-tests/cypress/e2e/projects_spec.js @@ -51,40 +51,16 @@ describe('Projects Tests', () => { cy.wait('@loadUserInfo'); cy.wait('@loadProjects'); - cy.clickButton('Project'); + cy.get('[data-cy="newProjectButton"]').click(); cy.get('[data-cy="projectName"]') .type('My New & test Project'); - cy.clickSave(); + cy.get('[data-cy="saveDialogBtn"]').click() cy.wait('@postNewProject'); cy.contains('My New & test Project'); }); - it('Provide clear instructions how to create a new project - root user', function () { - cy.logout(); - cy.fixture('vars.json') - .then((vars) => { - cy.login(vars.rootUser, vars.defaultPass); - }); - cy.visit('/administrator/'); - cy.contains('No Projects Yet...'); - cy.contains('A Project represents a gamified training profile that consists of skills divided into subjects'); - cy.get('[data-cy="firstNewProjectButton"]') - .click(); - cy.get('[data-cy="projectName"]') - .type('one'); - cy.get('[data-cy="saveProjectButton"]') - .click(); - cy.get('[data-cy="projCard_one_manageBtn"]'); - }); - - it('Provide clear instructions how to create a new project - regular user', function () { - cy.visit('/administrator/'); - cy.contains('No Projects Yet...'); - cy.contains('Note: This section of SkillTree is for project administrators only. If you do not plan on creating and integrating a project with SkillTree then please return to the Progress and Ranking page.'); - }); - it('Preview project training plan', function () { cy.request('POST', '/app/projects/proj1', { projectId: 'proj1', @@ -108,9 +84,9 @@ describe('Projects Tests', () => { name: 'proj1' }); cy.visit('/progress-and-rankings/projects/proj1'); - cy.dashboardCd() + cy.get('[data-cy="skillsDisplayHome"]') .contains('Overall Points'); - cy.contains('proj1'); + cy.get('[data-cy="skillsDisplayHome"] [data-cy="skillsTitle"]').contains('proj1'); }); it('Trusted client should be shown when oAuthOnly!=true', () => { @@ -155,51 +131,6 @@ describe('Projects Tests', () => { .should('exist'); }); - it('Project stats should all be the same size when they wrap', () => { - cy.viewport(1000, 1000); //original issue presented when stat cards wrapped to another row - - cy.request('POST', '/app/projects/abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy', { - projectId: 'abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy', - name: 'abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy' - }); - cy.intercept('GET', '/admin/projects/abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy') - .as('loadProj'); - cy.intercept('GET', '/api/projects/Inception/level') - .as('loadInception'); - cy.visit('/administrator/projects/abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy/'); - cy.wait('@loadProj'); - cy.wait('@loadInception'); - - cy.contains('No Subjects Yet'); - cy.get('[data-cy="pageHeader"]') - .contains('ID: abcdeghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy'); - cy.wait(2000); - cy.get('[data-cy="pageHeader"] .container-fluid') - .should('have.length', 1); - - cy.get('[data-cy=pageHeaderStat]') - .first() - .invoke('width') - .then((val) => { - cy.get('[data-cy=pageHeaderStat]') - .eq(1) - .invoke('width') - .should('eq', val); - cy.get('[data-cy=pageHeaderStat]') - .eq(2) - .invoke('width') - .should('eq', val); - cy.get('[data-cy=pageHeaderStat]') - .eq(3) - .invoke('width') - .should('eq', val); - cy.get('[data-cy=pageHeaderStat]') - .eq(4) - .invoke('width') - .should('eq', val); - }); - }); - it('Created and Last Reported Skill data should be visible on projects page', () => { cy.request('POST', '/app/projects/my_project_123', { projectId: 'my_project_123', @@ -328,7 +259,7 @@ describe('Projects Tests', () => { cy.contains('No Subjects Yet'); }); - it('project card stats', () => { + it('insufficient points warning', () => { cy.createProject(1); cy.createSubject(1, 1); cy.createSubject(1, 2); @@ -342,32 +273,11 @@ describe('Projects Tests', () => { cy.createProject(3); cy.visit('/administrator'); - cy.get('[data-cy="projectCard_proj1"] [data-cy="pagePreviewCardStat_Subjects"] [data-cy="statNum"]') - .contains(2); - cy.get('[data-cy="projectCard_proj1"] [data-cy="pagePreviewCardStat_Skills"] [data-cy="statNum"]') - .contains(3); - cy.get('[data-cy="projectCard_proj1"] [data-cy="pagePreviewCardStat_Points"] [data-cy="statNum"]') - .contains(600); - cy.get('[data-cy="projectCard_proj1"] [data-cy="pagePreviewCardStat_Badges"] [data-cy="statNum"]') - .contains(1); - - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Subjects"] [data-cy="statNum"]') - .contains(0); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Skills"] [data-cy="statNum"]') - .contains(0); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Points"] [data-cy="statNum"]') - .contains(0); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Badges"] [data-cy="statNum"]') - .contains(0); - - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Subjects"] [data-cy="warning"]') - .should('not.exist'); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Skills"] [data-cy="warning"]') - .should('not.exist'); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Points"] [data-cy="warning"]') - .should('exist'); - cy.get('[data-cy="projectCard_proj2"] [data-cy="pagePreviewCardStat_Badges"] [data-cy="warning"]') - .should('not.exist'); + cy.get('[data-cy="projectCard_proj1"] [data-cy="projectCardWarning"]').should('not.exist') + cy.get('[data-cy="projectCard_proj2"] [data-cy="projectCardWarning"]') + .contains('Project has insufficient points assigned'); + cy.get('[data-cy="projectCard_proj3"] [data-cy="projectCardWarning"]') + .contains('Project has insufficient points assigned'); }); it('project description is retained after editing', () => { @@ -385,22 +295,22 @@ describe('Projects Tests', () => { cy.wait('@loadDescription'); cy.get(makdownDivSelector).invoke('text').invoke('trim').should('equal', '') cy.get('[data-cy="markdownEditorInput"]').type('I am a description'); - cy.get('[data-cy="saveProjectButton"]').should('be.enabled'); - cy.get('[data-cy="saveProjectButton"]').click(); + cy.get('[data-cy="saveDialogBtn"]').should('be.enabled'); + cy.get('[data-cy="saveDialogBtn"]').click(); cy.wait('@saveProject'); cy.get('[data-cy="btn_edit-project"]').click(); cy.wait('@loadDescription'); cy.get(makdownDivSelector).should('have.text', 'I am a description'); cy.get('[data-cy="markdownEditorInput"]').click().type('jabberwocky jabberwocky jabberwocky'); cy.wait('@validateDescription'); - cy.get('[data-cy="projectDescriptionError"]').should('be.visible'); - cy.get('[data-cy="projectDescriptionError"]').should('contain.text', 'Project Description - paragraphs may not contain jabberwocky.'); - cy.get('[data-cy="saveProjectButton"]').should('be.disabled'); + cy.get('[data-cy="descriptionError"]').should('be.visible'); + cy.get('[data-cy="descriptionError"]').should('contain.text', 'Project Description - paragraphs may not contain jabberwocky'); + cy.get('[data-cy="saveDialogBtn"]').should('be.disabled'); cy.get('[data-cy="markdownEditorInput"]').click().type('{selectall}I am a description sans jw'); cy.wait('@validateDescription'); - cy.get('[data-cy="projectDescriptionError"]').should('not.be.visible'); - cy.get('[data-cy="saveProjectButton"]').should('be.enabled'); - cy.get('[data-cy="saveProjectButton"]').click(); + cy.get('[data-cy="descriptionError"]').should('not.be.visible'); + cy.get('[data-cy="saveDialogBtn"]').should('be.enabled'); + cy.get('[data-cy="saveDialogBtn"]').click(); cy.wait('@saveProject'); cy.visit('/administrator/'); cy.contains('This is project 1'); @@ -408,8 +318,8 @@ describe('Projects Tests', () => { cy.wait('@loadDescription'); cy.get(makdownDivSelector).should('have.text', 'I am a description sans jw'); cy.get('[data-cy="markdownEditorInput"]').click().type('{selectall}Am I a description?'); - cy.get('[data-cy="saveProjectButton"]').should('be.enabled'); - cy.get('[data-cy="saveProjectButton"]').click(); + cy.get('[data-cy="saveDialogBtn"]').should('be.enabled'); + cy.get('[data-cy="saveDialogBtn"]').click(); cy.wait('@saveProject'); cy.contains('This is project 1'); cy.get('[data-cy="editProjBtn"]').click();