From 5669387dccbbf65dcd47e9a250ce3b8e0ac6eef9 Mon Sep 17 00:00:00 2001 From: Elen Sargsyan Date: Wed, 6 Dec 2023 12:07:20 +0400 Subject: [PATCH 1/6] C388560 Auto-linking fields having $0 when creating new MARC Bib record (#2556) * C388560 Auto-linking fields having $0 when creating new MARC Bib record * added test * made requested changes --- .../auto-linking-fields-with-$0.cy.js | 251 ++++++++++++++++++ cypress/fixtures/marcAuthFileForC388560-1.mrc | 1 + cypress/fixtures/marcAuthFileForC388560-2.mrc | 1 + cypress/fixtures/marcAuthFileForC388560-3.mrc | 1 + cypress/fixtures/marcAuthFileForC388560-4.mrc | 1 + cypress/fixtures/marcAuthFileForC388560-5.mrc | 1 + .../inventory/inventoryViewSource.js | 19 ++ cypress/support/fragments/quickMarcEditor.js | 42 ++- 8 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 cypress/e2e/marc/marc-bibliographic/create-new-marc-bib/automated-linking/auto-linking-fields-with-$0.cy.js create mode 100644 cypress/fixtures/marcAuthFileForC388560-1.mrc create mode 100644 cypress/fixtures/marcAuthFileForC388560-2.mrc create mode 100644 cypress/fixtures/marcAuthFileForC388560-3.mrc create mode 100644 cypress/fixtures/marcAuthFileForC388560-4.mrc create mode 100644 cypress/fixtures/marcAuthFileForC388560-5.mrc diff --git a/cypress/e2e/marc/marc-bibliographic/create-new-marc-bib/automated-linking/auto-linking-fields-with-$0.cy.js b/cypress/e2e/marc/marc-bibliographic/create-new-marc-bib/automated-linking/auto-linking-fields-with-$0.cy.js new file mode 100644 index 0000000000..3eb342590b --- /dev/null +++ b/cypress/e2e/marc/marc-bibliographic/create-new-marc-bib/automated-linking/auto-linking-fields-with-$0.cy.js @@ -0,0 +1,251 @@ +import Permissions from '../../../../../support/dictionary/permissions'; +import DataImport from '../../../../../support/fragments/data_import/dataImport'; +import JobProfiles from '../../../../../support/fragments/data_import/job_profiles/jobProfiles'; +import Logs from '../../../../../support/fragments/data_import/logs/logs'; +import InventoryInstance from '../../../../../support/fragments/inventory/inventoryInstance'; +import MarcAuthority from '../../../../../support/fragments/marcAuthority/marcAuthority'; +import QuickMarcEditor from '../../../../../support/fragments/quickMarcEditor'; +import TopMenu from '../../../../../support/fragments/topMenu'; +import Users from '../../../../../support/fragments/users/users'; +import getRandomPostfix from '../../../../../support/utils/stringTools'; +import InventoryInstances from '../../../../../support/fragments/inventory/inventoryInstances'; +import InventoryViewSource from '../../../../../support/fragments/inventory/inventoryViewSource'; + +describe('MARC -> MARC Bibliographic -> Create new MARC bib -> Automated linking', () => { + const testData = { + tags: { + tag245: '245', + tagLDR: 'LDR', + }, + fieldContents: { + tag245Content: 'New title', + tagLDRContent: '00000naa\\a2200000uu\\4500', + }, + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + }; + + const newFields = [ + { + rowIndex: 4, + tag: '100', + content: '$a value', + status: 'not linked', + }, + { + rowIndex: 5, + tag: '240', + content: '$0 n99036055', + boxFourth: '$a Hosanna Bible', + boxFifth: '', + boxSixth: '$0 id.loc.gov/authorities/names/n99036055', + boxSeventh: '', + status: 'linked', + }, + { + rowIndex: 6, + tag: '610', + content: '$0 001002x', + status: 'not linked', + }, + { + rowIndex: 7, + tag: '711', + content: '$j something $0 n79084169C388560 $2 fast', + boxFourth: '$a Roma Council $c Basilica di San Pietro in Roma) $d 1962-1965 : $n (2nd :', + boxFifth: '$j something', + boxSixth: '$0 id.loc.gov/authorities/names/n79084169C388560', + boxSeventh: '$2 fast', + status: 'linked', + }, + { + rowIndex: 8, + tag: '830', + content: '$a something $d 1900-2000 $0 no2011188426', + boxFourth: '$a Robinson eminent scholar lecture series', + boxFifth: '', + boxSixth: '$0 id.loc.gov/authorities/names/no2011188426', + boxSeventh: '', + status: 'linked', + }, + ]; + + let userData = {}; + + const linkableFields = [100, 240, 610, 711, 830]; + + const marcFiles = [ + { + marc: 'marcAuthFileForC388560-1.mrc', + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + jobProfileToRun: 'Default - Create SRS MARC Authority', + numOfRecords: 1, + }, + { + marc: 'marcAuthFileForC388560-2.mrc', + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + jobProfileToRun: 'Default - Create SRS MARC Authority', + numOfRecords: 1, + }, + { + marc: 'marcAuthFileForC388560-3.mrc', + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + jobProfileToRun: 'Default - Create SRS MARC Authority', + numOfRecords: 1, + }, + { + marc: 'marcAuthFileForC388560-4.mrc', + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + jobProfileToRun: 'Default - Create SRS MARC Authority', + numOfRecords: 1, + }, + { + marc: 'marcAuthFileForC388560-5.mrc', + fileName: `testMarcFile.${getRandomPostfix()}.mrc`, + jobProfileToRun: 'Default - Create SRS MARC Authority', + numOfRecords: 1, + }, + ]; + + const createdAuthorityIDs = []; + let createdInstanceID; + + before(() => { + cy.createTempUser([ + Permissions.inventoryAll.gui, + Permissions.uiQuickMarcQuickMarcBibliographicEditorAll.gui, + Permissions.uiMarcAuthoritiesAuthorityRecordView.gui, + Permissions.uiQuickMarcQuickMarcBibliographicEditorCreate.gui, + Permissions.uiQuickMarcQuickMarcAuthorityLinkUnlink.gui, + ]).then((createdUserProperties) => { + userData = createdUserProperties; + + cy.loginAsAdmin().then(() => { + marcFiles.forEach((marcFile) => { + cy.visit(TopMenu.dataImportPath); + DataImport.verifyUploadState(); + DataImport.uploadFileAndRetry(marcFile.marc, marcFile.fileName); + JobProfiles.waitLoadingList(); + JobProfiles.search(marcFile.jobProfileToRun); + JobProfiles.runImportFile(); + JobProfiles.waitFileIsImported(marcFile.fileName); + Logs.checkStatusOfJobProfile('Completed'); + Logs.openFileDetails(marcFile.fileName); + for (let i = 0; i < marcFile.numOfRecords; i++) { + Logs.getCreatedItemsID(i).then((link) => { + createdAuthorityIDs.push(link.split('/')[5]); + }); + } + }); + }); + + linkableFields.forEach((tag) => { + QuickMarcEditor.setRulesForField(tag, true); + }); + + cy.login(userData.username, userData.password, { + path: TopMenu.inventoryPath, + waiter: InventoryInstances.waitContentLoading, + }); + }); + }); + + after('Deleting created users, Instances', () => { + cy.getAdminToken(); + Users.deleteViaApi(userData.userId); + createdAuthorityIDs.forEach((id) => { + MarcAuthority.deleteViaAPI(id); + }); + InventoryInstance.deleteInstanceViaApi(createdInstanceID); + }); + + it( + 'C388560 Auto-linking fields having "$0" when creating new "MARC Bib" record (spitfire) (TaaS)', + { tags: ['extendedPath', 'spitfire'] }, + () => { + InventoryInstance.newMarcBibRecord(); + QuickMarcEditor.updateExistingField( + testData.tags.tag245, + `$a ${testData.fieldContents.tag245Content}`, + ); + QuickMarcEditor.updateExistingField( + testData.tags.tagLDR, + testData.fieldContents.tagLDRContent, + ); + newFields.forEach((newField) => { + MarcAuthority.addNewField(newField.rowIndex, newField.tag, newField.content); + }); + QuickMarcEditor.clickLinkHeadingsButton(); + QuickMarcEditor.checkCallout( + 'Field 240, 711, and 830 has been linked to MARC authority record(s).', + ); + QuickMarcEditor.checkCallout('Field 610 must be set manually by selecting the link icon.'); + QuickMarcEditor.verifyEnabledLinkHeadingsButton(); + newFields.forEach((newField) => { + if (newField.status === 'linked') { + QuickMarcEditor.verifyTagFieldAfterLinking( + newField.rowIndex + 1, + newField.tag, + '\\', + '\\', + `${newField.boxFourth}`, + `${newField.boxFifth}`, + `${newField.boxSixth}`, + `${newField.boxSeventh}`, + ); + } else { + QuickMarcEditor.verifyTagFieldNotLinked( + newField.rowIndex + 1, + newField.tag, + '\\', + '\\', + newField.content, + ); + } + }); + QuickMarcEditor.addNewField('700', '$a smth $0 3052044', 9); + QuickMarcEditor.updateExistingField('610', '$0 n93094742'); + QuickMarcEditor.pressSaveAndClose(); + + QuickMarcEditor.checkAfterSaveAndClose(); + InventoryInstance.getId().then((id) => { + createdInstanceID = id; + }); + InventoryInstance.viewSource(); + newFields.forEach((newField) => { + if (newField.status === 'linked') { + InventoryViewSource.verifyLinkedToAuthorityIcon(newField.rowIndex + 1, true); + } else { + InventoryViewSource.verifyLinkedToAuthorityIcon(newField.rowIndex + 1, false); + } + }); + QuickMarcEditor.closeEditorPane(); + InventoryInstance.waitLoading(); + InventoryInstance.editMarcBibliographicRecord(); + QuickMarcEditor.verifyEnabledLinkHeadingsButton(); + newFields.forEach((newField) => { + if (newField.status === 'linked') { + QuickMarcEditor.verifyTagFieldAfterLinking( + newField.rowIndex + 1, + newField.tag, + '\\', + '\\', + `${newField.boxFourth}`, + `${newField.boxFifth}`, + `${newField.boxSixth}`, + `${newField.boxSeventh}`, + ); + } else if (newField.tag !== '610') { + QuickMarcEditor.verifyTagFieldNotLinked( + newField.rowIndex + 1, + newField.tag, + '\\', + '\\', + newField.content, + ); + } + }); + QuickMarcEditor.verifyTagFieldNotLinked(7, '610', '\\', '\\', '$0 n93094742'); + QuickMarcEditor.verifyTagFieldNotLinked(10, '700', '\\', '\\', '$a smth $0 3052044'); + }, + ); +}); diff --git a/cypress/fixtures/marcAuthFileForC388560-1.mrc b/cypress/fixtures/marcAuthFileForC388560-1.mrc new file mode 100644 index 0000000000..15a7698358 --- /dev/null +++ b/cypress/fixtures/marcAuthFileForC388560-1.mrc @@ -0,0 +1 @@ +00697nz a2200169n 4500001000800000005001700008008004100025010001700066035002300083040002200106130004400128410011600172644001300288645001300301646001300314670020000327884757720111208074537.0111207n| acaabaaan |a ana c ano2011188426 a(OCoLC)oca09056284 aFJUNFbengcFJUNF 0aRobinson eminent scholar lecture series2 aUniversity of North Florida.bCollege of Education and Human Services.tRobinson eminent scholar lecture series af5FJUNF at5FJUNF as5FJUNF aSanders, William L. Beyond No Child Left Behind, 2005:bprogram t.p. (The University of North Florida College of Education and Human Services presents ... Robinson eminent scholar lecture series) \ No newline at end of file diff --git a/cypress/fixtures/marcAuthFileForC388560-2.mrc b/cypress/fixtures/marcAuthFileForC388560-2.mrc new file mode 100644 index 0000000000..23993d09af --- /dev/null +++ b/cypress/fixtures/marcAuthFileForC388560-2.mrc @@ -0,0 +1 @@ +00401nz a2200145n 450000100070000000500170000700800410002401000170006503500210008204000180010310000430012140000500016467000320021495300090024692724919990513143117.3990513n| acannaabn |a aaa  an 99036055  a(DLC)n 99036055 aDLCbengcDLC10aAbraham, Angela,d1958-tHosanna Bible10aAbraham, Angela,d1958-tJesus loves me Bible aJesus loves me Bible, 1999. ash21 \ No newline at end of file diff --git a/cypress/fixtures/marcAuthFileForC388560-3.mrc b/cypress/fixtures/marcAuthFileForC388560-3.mrc new file mode 100644 index 0000000000..4924e70858 --- /dev/null +++ b/cypress/fixtures/marcAuthFileForC388560-3.mrc @@ -0,0 +1 @@ +04611cz a2200721n 4500001001300000005001700013008004100030016001500071035002300086040006700109042000800176046002100184111008800205368003000293370001900323373004000342377000800382411007700390410009300467410008900560411008500649411007100734411008600805411007200891411007500963411010101038411007901139411007301218411006801291411008201359411006901441411006901510411007001579411007101649411007101720411007201791411007801863411007901941411008002020411008302100411007802183411008002261411007802341411008002419411009502499411004302594411007302637670002902710670005902739670019502798670009602993670005303089670008303142670007003225670006503295670009503360670006403455670014603519670011403665670008503779952001003864953001503874n 79084169C388560 20211113064556.0791004n| azannaabn |a ana  a0100K3322E a(OCoLC)oca00316673 aDLCbengerdacDLCdDLCdICUdDLCdMoSUdUPBdWaUdCaOONLdICU anlc s1962t19652edtf2 aRoma Counciln(2nd :d1962-1965 :cBasilica di San Pietro in Roma)jterm2trl4test aCouncils and synods2lcsh eRoma City2naf aBasilica di San Pietro in Roma2naf alat2 aBachikan Kōkaigin(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aCatholic Church.bConcilium Romaumn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aCatholic Church.bRoma Counciln(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aConcile œcuménique Roman(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aConcile Roman(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aConcilio ecumenico vaticanon(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aConcilio Roman(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aConcilium Romaumn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aMajmaʻ al-Maskūnī al-Vātīkānīn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aSobór Watykańskin(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVaticà II (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aRoma 2 (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aRoma Ecumenical Counciln(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aRoma II (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aRoma II (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aRomaum 2 (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aRomaum II (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aVatikan 2 (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aVatikan II (Council)d(1962-1965 :cBasilica di San Pietro in Roma)2 aVatikaneios Synodosn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikanisches Konziln(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikano susirinkimasn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikanski cerkveni zborn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikánsky konciln(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikánský sněmn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatikanum (Council)n(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVatykansʹkyĭ Soborn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 aVselensʹkyĭ Sobor Vatykansʹkyĭn(2nd :d1962-1965 :cBasilica di San Pietro in Roma)2 wnneaaRoma Counciln(2nd :d1962-1965)2 aConcile du Roman(2e :d1962-1965 :cBasilica di San Pietro in Roma) aDaniel-Rops, H. Roma II. aLa Impossible restauració, 1986:bt.p. (Vaticà II) aKarmirēs, I. Hē Vʹ Vatikaneios Synodos kai hē enanti autēs kai tōn henōtikōn taseōn tēs thesis tēs Orthodoxou Katholikēs Ekklēsias, 1964:bt.p. (Vatikaneios Synodos) aFerraro, J. Durkheim y el totemismo en la religión contemporánea, 1985:bt.p. (Roma II) aFrance-Allemagne, c1988:bt.p. (Concile Roma II) aKatalikybės filosofinės koncepcijos, 1986:bt.p. (II Vatikano susirinkimo) aUkrainsʹka t︠s︡erkva na druhomu Vatykansʹkomu Soboru, 1995. aLobkowicz, N. Das Menschenbild des zweiten Vatikanum, c1989. aFoundations for the renewal of the diaconate, 1993:bp. 1 (Second Roma Ecumenical Council) aGereja Indonesia pasca-Vatikan II, 1997:bt.p. (Vatikan II) aSlovenski škofje na drugem vatikanskem vesoljnem cerkvenem zboru (1962-1965), 1992:bt.p. (... drugem Vatikanskem vesoljnem cervenem zboru) aLAC internal file, June 19, 2019b(variant: Concile du Roma (2e : 1962-1965 : Basilica di San Pietro in Roma) aDruhý vatikánský sněm, 1983:btitle page (Druhý vatikánský sněm) aRETRO axx00bwj04 diff --git a/cypress/fixtures/marcAuthFileForC388560-4.mrc b/cypress/fixtures/marcAuthFileForC388560-4.mrc new file mode 100644 index 0000000000..cb6d5f8207 --- /dev/null +++ b/cypress/fixtures/marcAuthFileForC388560-4.mrc @@ -0,0 +1 @@ +01919cz a2200337n 4500001000800000005001700008008004100025010002000066016001500086035002300101040005300124042000800177046003300185053001700218065003200235100005700267370005400324371002900378372002400407373008500431374001800516375001700534377000800551670005500559670006700614670026000681670026800941670008201209670027501291953001501566305204420221008174227.0900423n| azannaabn |n aaa  a0255869z123123 a0051J2038E a(OCoLC)oca02727665 aDLCbengerdacDLCdDLCdOCoLCdUPBdCaOONLdOkU anlc f1950-03-17g2022-10-042edtf 0aPR6068.O1964 aPS8585.O351762fcps5CaOONL1 aJackson, Peter,d1950-2022cInspector Banks series ; aCastleford (England)cCanadaeToronto (Ont.)2naf madmin@inspectorbanks.com aCrime writing2lcsh aUniversity of LeedsaUniversity of WindsoraYork University (Toronto, Ont.)2naf aAuthors2lcsh aMales2lcdgt aeng aHis Gallows view, c1990:bCIP t.p. (Peter Jackson) aTelephone call to publisher, 4-20-90b(Peter Jackson; b. 1950) aPeter Jackson, via WWW, Oct. 1, 2012b(born in Yorkshire; B.A. Honours, English Literature, University of Leeds; M.A., English and Creative Writing, University of Windsor in Canada; PhD, English, York University; Author of crime novels and short stories) aWikipedia, via WWW, Oct. 1, 2012b(born March 17, 1950 in Castleford, Yorkshire; English crime writer, based in Canada; lives in Toronto with his wife; teaches crime writing at University of Toronto; has served as Writer-in-Residence at the University of Windsor) aLAC internal file, April 26, 2019b(heading: Jackson, Peter, 1950-; Canadian) aHodder & Stoughton, Oct. 7, 2022:b(Hodder & Stoughton are sad to announce that the crime writer Peter Jackson died suddenly on 4th October after a brief illness.)uhttps://www.hodder.co.uk/hachette-news/2022/10/07/hodder-stoughton-announces-the-death-of-peter-robinson/ abd07bzz00 \ No newline at end of file diff --git a/cypress/fixtures/marcAuthFileForC388560-5.mrc b/cypress/fixtures/marcAuthFileForC388560-5.mrc new file mode 100644 index 0000000000..a0266dc713 --- /dev/null +++ b/cypress/fixtures/marcAuthFileForC388560-5.mrc @@ -0,0 +1 @@ +00585cz a2200157n 4500001000800000005001700008008004100025010001700066035002100083040001800104110005800122410003600180410003800216670016400254953000900418451095519931001145917.5930927n| acannaab |a anc  an 93094742  a(DLC)n 93094742 aDLCcDLCdDLC20aRadio "Vaticana".bHrvatski programu(added subfield)20aHrvatski program Radio Vatikana20aRadio Vaticana.bHrvatska sekcija aBeljan J. Radio i Kristov evanđeoski nalog, 1991:bp v., etc. (Radio Vatikan/Hrvatski program) p. 123 (Hrvatski program Radio Vatikana) 125 (Hrvatska sekcija) ash09 \ No newline at end of file diff --git a/cypress/support/fragments/inventory/inventoryViewSource.js b/cypress/support/fragments/inventory/inventoryViewSource.js index 51d53f5913..cf6d0673e6 100644 --- a/cypress/support/fragments/inventory/inventoryViewSource.js +++ b/cypress/support/fragments/inventory/inventoryViewSource.js @@ -5,6 +5,7 @@ const instanceTitle = 'MARC bibliographic record'; const holdingTitle = 'Holdings record'; const closeButton = Button({ icon: 'times' }); const rootSection = Section({ id: 'marc-view-pane' }); +const linkedToMarcAuthorityIcon = Button({ href: including('/marc-authorities/authorities/') }); const close = () => cy.do(closeButton.click()); const contains = (expectedText) => cy.expect(rootSection.find(HTML(including(expectedText))).exists()); @@ -77,4 +78,22 @@ export default { }); } }, + + verifyLinkedToAuthorityIcon(rowIndex, isPresent = true) { + if (isPresent) { + cy.expect( + rootSection + .find(TableRow({ index: rowIndex })) + .find(linkedToMarcAuthorityIcon) + .exists(), + ); + } else { + cy.expect( + rootSection + .find(TableRow({ index: rowIndex })) + .find(linkedToMarcAuthorityIcon) + .absent(), + ); + } + }, }; diff --git a/cypress/support/fragments/quickMarcEditor.js b/cypress/support/fragments/quickMarcEditor.js index 5dd8d7cb38..267f8cb8ea 100644 --- a/cypress/support/fragments/quickMarcEditor.js +++ b/cypress/support/fragments/quickMarcEditor.js @@ -32,7 +32,7 @@ const addFieldButton = Button({ ariaLabel: 'plus-sign' }); const deleteFieldButton = Button({ ariaLabel: 'trash' }); const linkToMarcRecordButton = Button({ ariaLabel: 'link' }); const unlinkIconButton = Button({ ariaLabel: 'unlink' }); -const viewAuthorutyIconButton = Button({ ariaLabel: 'eye-open' }); +const viewAuthorityIconButton = Button({ ariaLabel: 'eye-open' }); const arrowUpButton = Button({ ariaLabel: 'arrow-up' }); const saveAndCloseButton = Button({ id: 'quick-marc-record-save' }); const saveAndKeepEditingBtn = Button({ id: 'quick-marc-record-save-edit' }); @@ -807,7 +807,7 @@ export default { cy.expect([ Callout(`Field ${tag} has been linked to a MARC authority record.`).exists(), QuickMarcEditorRow({ tagValue: tag }).find(unlinkIconButton).exists(), - QuickMarcEditorRow({ tagValue: tag }).find(viewAuthorutyIconButton).exists(), + QuickMarcEditorRow({ tagValue: tag }).find(viewAuthorityIconButton).exists(), ]); }, @@ -815,14 +815,14 @@ export default { cy.expect([ Callout(`Field ${tag} has been linked to a MARC authority record.`).exists(), QuickMarcEditorRow({ index: rowIndex }).find(unlinkIconButton).exists(), - QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorutyIconButton).exists(), + QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorityIconButton).exists(), ]); }, verifyUnlinkAndViewAuthorityButtons(rowIndex) { cy.expect([ QuickMarcEditorRow({ index: rowIndex }).find(unlinkIconButton).exists(), - QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorutyIconButton).exists(), + QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorityIconButton).exists(), ]); }, @@ -881,6 +881,36 @@ export default { ]); }, + verifyTagFieldNotLinked(rowIndex, tag, secondBox, thirdBox, content) { + cy.expect([ + QuickMarcEditorRow({ index: rowIndex }) + .find(TextField({ name: `records[${rowIndex}].tag` })) + .has({ value: tag }), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextField({ name: `records[${rowIndex}].indicators[0]` })) + .has({ value: secondBox }), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextField({ name: `records[${rowIndex}].indicators[1]` })) + .has({ value: thirdBox }), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextArea({ name: `records[${rowIndex}].content` })) + .has({ value: including(content) }), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextArea({ name: `records[${rowIndex}].subfieldGroups.controlled` })) + .absent(), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextArea({ name: `records[${rowIndex}].subfieldGroups.uncontrolledAlpha` })) + .absent(), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextArea({ name: `records[${rowIndex}].subfieldGroups.zeroSubfield` })) + .absent(), + QuickMarcEditorRow({ index: rowIndex }) + .find(TextArea({ name: `records[${rowIndex}].subfieldGroups.uncontrolledNumber` })) + .absent(), + QuickMarcEditorRow({ index: rowIndex }).find(linkToMarcRecordButton).exists(), + ]); + }, + verifyTagField(rowIndex, tag, secondBox, thirdBox, subfieldS, subfieldI) { cy.expect([ QuickMarcEditorRow({ index: rowIndex }) @@ -1537,7 +1567,7 @@ export default { cy.expect([ Callout(`Field ${tag} has been linked to a MARC authority record.`).exists(), QuickMarcEditorRow({ index: rowIndex }).find(unlinkIconButton).exists(), - QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorutyIconButton).exists(), + QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorityIconButton).exists(), ]); }, @@ -1753,7 +1783,7 @@ export default { verifyIconsAfterUnlinking(rowIndex) { cy.expect([ QuickMarcEditorRow({ index: rowIndex }).find(unlinkIconButton).absent(), - QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorutyIconButton).absent(), + QuickMarcEditorRow({ index: rowIndex }).find(viewAuthorityIconButton).absent(), QuickMarcEditorRow({ index: rowIndex }).find(linkToMarcRecordButton).exists(), ]); }, From cbffee1e5b5841505d3644ebaf29024bbeff9ca3 Mon Sep 17 00:00:00 2001 From: Daniil Novikau Date: Wed, 6 Dec 2023 12:26:10 +0300 Subject: [PATCH 2/6] [353621] 'Organization type' is present in exported file --- cypress/e2e/orders/export-orders.cy.js | 86 ------------ cypress/e2e/orders/export/export-orders.cy.js | 88 ++++++++++++ ...zation-type-present-in-exported-file.cy.js | 111 +++++++++++++++ .../orders/export/pol-export-by-filters.cy.js | 129 ++++++++++++++++++ .../e2e/orders/pol-export-by-filters.cy.js | 123 ----------------- .../orders/modals/exportSettingsModal.js | 79 +++++++++++ .../orders/modals/selectOrganizationModal.js | 20 +++ .../support/fragments/orders/orderLines.js | 20 +-- .../support/fragments/orders/orderStates.js | 1 + cypress/support/fragments/orders/orders.js | 20 ++- .../organizations/settingsOrganizations.js | 9 ++ cypress/support/utils/fileManager.js | 8 ++ 12 files changed, 464 insertions(+), 230 deletions(-) delete mode 100644 cypress/e2e/orders/export-orders.cy.js create mode 100644 cypress/e2e/orders/export/export-orders.cy.js create mode 100644 cypress/e2e/orders/export/organization-type-present-in-exported-file.cy.js create mode 100644 cypress/e2e/orders/export/pol-export-by-filters.cy.js delete mode 100644 cypress/e2e/orders/pol-export-by-filters.cy.js create mode 100644 cypress/support/fragments/orders/modals/exportSettingsModal.js create mode 100644 cypress/support/fragments/orders/modals/selectOrganizationModal.js diff --git a/cypress/e2e/orders/export-orders.cy.js b/cypress/e2e/orders/export-orders.cy.js deleted file mode 100644 index 17dd96b064..0000000000 --- a/cypress/e2e/orders/export-orders.cy.js +++ /dev/null @@ -1,86 +0,0 @@ -import permissions from '../../support/dictionary/permissions'; -import NewInvoice from '../../support/fragments/invoices/newInvoice'; -import BasicOrderLine from '../../support/fragments/orders/basicOrderLine'; -import NewOrder from '../../support/fragments/orders/newOrder'; -import Orders from '../../support/fragments/orders/orders'; -import OrdersHelper from '../../support/fragments/orders/ordersHelper'; -import NewOrganization from '../../support/fragments/organizations/newOrganization'; -import Organizations from '../../support/fragments/organizations/organizations'; -import TopMenu from '../../support/fragments/topMenu'; -import Users from '../../support/fragments/users/users'; -import FileManager from '../../support/utils/fileManager'; -import generateItemBarcode from '../../support/utils/generateItemBarcode'; - -describe('orders: export', () => { - let user; - const organization = { ...NewOrganization.defaultUiOrganizations }; - const order = { - ...NewOrder.defaultOneTimeOrder, - poNumberPrefix: 'pref', - poNumberSuffix: 'suf', - poNumber: `pref${generateItemBarcode()}suf`, - reEncumber: true, - manualPo: true, - approved: true, - }; - const orderLine = { ...BasicOrderLine.defaultOrderLine }; - const invoice = { ...NewInvoice.defaultUiInvoice }; - let orderNumber; - before(() => { - cy.getAdminToken(); - Organizations.createOrganizationViaApi(organization).then((response) => { - organization.id = response; - order.vendor = response; - orderLine.physical.materialSupplier = response; - orderLine.eresource.accessProvider = response; - }); - invoice.vendorName = organization.name; - cy.getLocations({ query: `name="${OrdersHelper.mainLibraryLocation}"` }).then((location) => { - orderLine.locations[0].locationId = location.id; - }); - cy.getMaterialTypes({ query: 'name="book"' }).then((materialType) => { - orderLine.physical.materialType = materialType.id; - cy.login(Cypress.env('diku_login'), Cypress.env('diku_password')); - cy.createOrderApi(order).then((response) => { - orderNumber = response.body.poNumber; - cy.getAcquisitionMethodsApi({ query: 'value="Other"' }).then((params) => { - orderLine.acquisitionMethod = params.body.acquisitionMethods[0].id; - orderLine.purchaseOrderId = order.id; - cy.createOrderLineApi(orderLine); - }); - cy.visit(TopMenu.ordersPath); - Orders.searchByParameter('PO number', orderNumber); - Orders.selectFromResultsList(orderNumber); - Orders.openOrder(); - Orders.closeThirdPane(); - Orders.resetFilters(); - }); - }); - cy.createTempUser([permissions.uiOrdersView.gui, permissions.uiExportOrders.gui]).then( - (userProperties) => { - user = userProperties; - cy.login(user.username, user.password, { - path: TopMenu.ordersPath, - waiter: Orders.waitLoading, - }); - }, - ); - }); - - after(() => { - cy.getAdminToken(); - Orders.deleteOrderViaApi(order.id); - Organizations.deleteOrganizationViaApi(organization.id); - Users.deleteViaApi(user.userId); - FileManager.deleteFolder(Cypress.config('downloadsFolder')); - }); - - it( - 'C196749 Export orders based on orders search (thunderjet)', - { tags: ['smoke', 'thunderjet'] }, - () => { - Orders.selectOpenStatusFilter(); - Orders.exportResoultsCSV(); - }, - ); -}); diff --git a/cypress/e2e/orders/export/export-orders.cy.js b/cypress/e2e/orders/export/export-orders.cy.js new file mode 100644 index 0000000000..abea76f8e1 --- /dev/null +++ b/cypress/e2e/orders/export/export-orders.cy.js @@ -0,0 +1,88 @@ +import permissions from '../../../support/dictionary/permissions'; +import NewInvoice from '../../../support/fragments/invoices/newInvoice'; +import BasicOrderLine from '../../../support/fragments/orders/basicOrderLine'; +import NewOrder from '../../../support/fragments/orders/newOrder'; +import Orders from '../../../support/fragments/orders/orders'; +import OrdersHelper from '../../../support/fragments/orders/ordersHelper'; +import NewOrganization from '../../../support/fragments/organizations/newOrganization'; +import Organizations from '../../../support/fragments/organizations/organizations'; +import TopMenu from '../../../support/fragments/topMenu'; +import Users from '../../../support/fragments/users/users'; +import FileManager from '../../../support/utils/fileManager'; +import generateItemBarcode from '../../../support/utils/generateItemBarcode'; + +describe('Orders', () => { + describe('Export', () => { + let user; + const organization = { ...NewOrganization.defaultUiOrganizations }; + const order = { + ...NewOrder.defaultOneTimeOrder, + poNumberPrefix: 'pref', + poNumberSuffix: 'suf', + poNumber: `pref${generateItemBarcode()}suf`, + reEncumber: true, + manualPo: true, + approved: true, + }; + const orderLine = { ...BasicOrderLine.defaultOrderLine }; + const invoice = { ...NewInvoice.defaultUiInvoice }; + let orderNumber; + before(() => { + cy.getAdminToken(); + Organizations.createOrganizationViaApi(organization).then((response) => { + organization.id = response; + order.vendor = response; + orderLine.physical.materialSupplier = response; + orderLine.eresource.accessProvider = response; + }); + invoice.vendorName = organization.name; + cy.getLocations({ query: `name="${OrdersHelper.mainLibraryLocation}"` }).then((location) => { + orderLine.locations[0].locationId = location.id; + }); + cy.getMaterialTypes({ query: 'name="book"' }).then((materialType) => { + orderLine.physical.materialType = materialType.id; + cy.login(Cypress.env('diku_login'), Cypress.env('diku_password')); + cy.createOrderApi(order).then((response) => { + orderNumber = response.body.poNumber; + cy.getAcquisitionMethodsApi({ query: 'value="Other"' }).then((params) => { + orderLine.acquisitionMethod = params.body.acquisitionMethods[0].id; + orderLine.purchaseOrderId = order.id; + cy.createOrderLineApi(orderLine); + }); + cy.visit(TopMenu.ordersPath); + Orders.searchByParameter('PO number', orderNumber); + Orders.selectFromResultsList(orderNumber); + Orders.openOrder(); + Orders.closeThirdPane(); + Orders.resetFilters(); + }); + }); + cy.createTempUser([permissions.uiOrdersView.gui, permissions.uiExportOrders.gui]).then( + (userProperties) => { + user = userProperties; + cy.login(user.username, user.password, { + path: TopMenu.ordersPath, + waiter: Orders.waitLoading, + }); + }, + ); + }); + + after(() => { + cy.getAdminToken(); + Orders.deleteOrderViaApi(order.id); + Organizations.deleteOrganizationViaApi(organization.id); + Users.deleteViaApi(user.userId); + FileManager.deleteFolder(Cypress.config('downloadsFolder')); + }); + + it( + 'C196749 Export orders based on orders search (thunderjet)', + { tags: ['smoke', 'thunderjet'] }, + () => { + Orders.selectOpenStatusFilter(); + Orders.exportResultsToCsv(); + }, + ); + }); +}); diff --git a/cypress/e2e/orders/export/organization-type-present-in-exported-file.cy.js b/cypress/e2e/orders/export/organization-type-present-in-exported-file.cy.js new file mode 100644 index 0000000000..db4cb6e8f3 --- /dev/null +++ b/cypress/e2e/orders/export/organization-type-present-in-exported-file.cy.js @@ -0,0 +1,111 @@ +import moment from 'moment'; + +import { Permissions } from '../../../support/dictionary'; +import { NewOrder, Orders, BasicOrderLine } from '../../../support/fragments/orders'; +import { NewOrganization, Organizations } from '../../../support/fragments/organizations'; +import SettingsOrganizations from '../../../support/fragments/settings/organizations/settingsOrganizations'; +import TopMenu from '../../../support/fragments/topMenu'; +import Users from '../../../support/fragments/users/users'; +import FileManager from '../../../support/utils/fileManager'; + +describe('Orders', () => { + describe('Export', () => { + const organizationTypes = [ + SettingsOrganizations.getDefaultOrganizationType(), + SettingsOrganizations.getDefaultOrganizationType(), + SettingsOrganizations.getDefaultOrganizationType(), + ]; + const testData = { + organizationTypes, + organizationTypesNames: organizationTypes.map(({ name }) => `"${name}"`).join(' | '), + organization: { + ...NewOrganization.getDefaultOrganization(), + organizationTypes: organizationTypes.map(({ id }) => id), + }, + fileName: `order-export-${moment().format('YYYY-MM-DD')}-*.csv`, + user: {}, + }; + + before('Create test data', () => { + cy.getAdminToken().then(() => { + testData.organizationTypes.forEach((organizationType) => { + SettingsOrganizations.createTypesViaApi(organizationType); + }); + Organizations.createOrganizationViaApi(testData.organization).then(() => { + testData.order = NewOrder.getDefaultOngoingOrder({ vendorId: testData.organization.id }); + testData.orderLine = BasicOrderLine.getDefaultOrderLine(); + + Orders.createOrderWithOrderLineViaApi(testData.order, testData.orderLine).then( + (order) => { + testData.order = order; + }, + ); + }); + }); + + cy.createTempUser([Permissions.uiOrdersView.gui, Permissions.uiExportOrders.gui]).then( + (userProperties) => { + testData.user = userProperties; + + cy.login(testData.user.username, testData.user.password, { + path: TopMenu.ordersPath, + waiter: Orders.waitLoading, + }); + }, + ); + }); + + after('Delete test data', () => { + cy.getAdminToken().then(() => { + FileManager.deleteFilesFromDownloadsByMask(testData.fileName); + Organizations.deleteOrganizationViaApi(testData.organization.id); + testData.organizationTypes.forEach((organizationType) => { + SettingsOrganizations.deleteOrganizationTypeViaApi(organizationType.id); + }); + Orders.deleteOrderViaApi(testData.order.id); + Users.deleteViaApi(testData.user.userId); + }); + }); + + it( + 'C353621 "Organization type" is present in exported .csv order (thunderjet) (TaaS)', + { tags: ['extendedPath', 'thunderjet'] }, + () => { + // Search for the order from Preconditions + Orders.searchByParameter('PO number', testData.order.poNumber); + + // Click "Actions" button on "Orders" pane and select "Export results (CSV)" option + const ExportSettingsModal = Orders.clickExportResultsToCsvButton(); + + // Click radio button to activate "PO fields to export" dropdown field + ExportSettingsModal.selectOrderFieldsToExport('Organization type'); + + // Click "Export" button + ExportSettingsModal.clickExportButton(); + + // Open downloaded file, Check "Organization type" results are present + FileManager.convertCsvToJson(testData.fileName).then((data) => { + data.forEach((order) => { + cy.expect(order['"Organizationtype"']).to.equal(testData.organizationTypesNames); + }); + }); + + // Search for the order from Preconditions + Orders.searchByParameter('PO number', testData.order.poNumber); + + // Click "Actions" button on "Orders" pane and select "Export results (CSV)" option + Orders.clickExportResultsToCsvButton(); + + // Click "Export" button + ExportSettingsModal.clickExportButton(); + + // Open downloaded file, Check "Organization type" results are present + FileManager.convertCsvToJson(testData.fileName).then((data) => { + data.forEach((order) => { + cy.expect(order['"Organizationtype"']).to.equal(testData.organizationTypesNames); + }); + }); + }, + ); + }); +}); diff --git a/cypress/e2e/orders/export/pol-export-by-filters.cy.js b/cypress/e2e/orders/export/pol-export-by-filters.cy.js new file mode 100644 index 0000000000..f577908584 --- /dev/null +++ b/cypress/e2e/orders/export/pol-export-by-filters.cy.js @@ -0,0 +1,129 @@ +import moment from 'moment'; + +import permissions from '../../../support/dictionary/permissions'; +import FinanceHelp from '../../../support/fragments/finance/financeHelper'; +import FiscalYears from '../../../support/fragments/finance/fiscalYears/fiscalYears'; +import Funds from '../../../support/fragments/finance/funds/funds'; +import Ledgers from '../../../support/fragments/finance/ledgers/ledgers'; +import Invoices from '../../../support/fragments/invoices/invoices'; +import NewInvoice from '../../../support/fragments/invoices/newInvoice'; +import NewOrder from '../../../support/fragments/orders/newOrder'; +import OrderLines from '../../../support/fragments/orders/orderLines'; +import Orders from '../../../support/fragments/orders/orders'; +import NewOrganization from '../../../support/fragments/organizations/newOrganization'; +import Organizations from '../../../support/fragments/organizations/organizations'; +import NewLocation from '../../../support/fragments/settings/tenant/locations/newLocation'; +import ServicePoints from '../../../support/fragments/settings/tenant/servicePoints/servicePoints'; +import TopMenu from '../../../support/fragments/topMenu'; +import Users from '../../../support/fragments/users/users'; +import FileManager from '../../../support/utils/fileManager'; + +describe('Orders', () => { + describe('Export', () => { + const firstFiscalYear = { ...FiscalYears.defaultRolloverFiscalYear }; + const defaultLedger = { ...Ledgers.defaultUiLedger }; + const defaultFund = { ...Funds.defaultUiFund }; + const defaultOrder = { + ...NewOrder.defaultOneTimeOrder, + orderType: 'Ongoing', + ongoing: { isSubscription: false, manualRenewal: false }, + approved: true, + reEncumber: true, + }; + const organization = { ...NewOrganization.defaultUiOrganizations }; + const invoice = { ...NewInvoice.defaultUiInvoice }; + const allocatedQuantity = '100'; + const fileName = `order-export-${moment().format('YYYY-MM-DD')}-*.csv`; + let user; + let firstOrderNumber; + let servicePointId; + let location; + + before(() => { + cy.getAdminToken(); + FiscalYears.createViaApi(firstFiscalYear).then((firstFiscalYearResponse) => { + firstFiscalYear.id = firstFiscalYearResponse.id; + defaultLedger.fiscalYearOneId = firstFiscalYear.id; + Ledgers.createViaApi(defaultLedger).then((ledgerResponse) => { + defaultLedger.id = ledgerResponse.id; + defaultFund.ledgerId = defaultLedger.id; + + Funds.createViaApi(defaultFund).then((fundResponse) => { + defaultFund.id = fundResponse.fund.id; + + cy.loginAsAdmin({ path: TopMenu.fundPath, waiter: Funds.waitLoading }); + FinanceHelp.searchByName(defaultFund.name); + Funds.selectFund(defaultFund.name); + Funds.addBudget(allocatedQuantity); + }); + }); + }); + ServicePoints.getViaApi().then((servicePoint) => { + servicePointId = servicePoint[0].id; + NewLocation.createViaApi(NewLocation.getDefaultLocation(servicePointId)).then((res) => { + location = res; + }); + }); + Organizations.createOrganizationViaApi(organization).then((responseOrganizations) => { + organization.id = responseOrganizations; + invoice.accountingCode = organization.erpCode; + }); + defaultOrder.vendor = organization.name; + cy.visit(TopMenu.ordersPath); + Orders.createOrderForRollover(defaultOrder).then((firstOrderResponse) => { + defaultOrder.id = firstOrderResponse.id; + firstOrderNumber = firstOrderResponse.poNumber; + Orders.checkCreatedOrder(defaultOrder); + OrderLines.addPOLine(); + OrderLines.selectRandomInstanceInTitleLookUP('*', 5); + OrderLines.rolloverPOLineInfoforPhysicalMaterialWithFund( + defaultFund, + '40', + '1', + '40', + location.institutionId, + ); + OrderLines.backToEditingOrder(); + Orders.openOrder(); + cy.visit(TopMenu.invoicesPath); + Invoices.createRolloverInvoice(invoice, organization.name); + Invoices.createInvoiceLineFromPol(firstOrderNumber); + // Need to wait, while data will be loaded + cy.wait(4000); + Invoices.approveInvoice(); + Invoices.payInvoice(); + }); + + cy.createTempUser([permissions.uiExportOrders.gui, permissions.uiOrdersView.gui]).then( + (userProperties) => { + user = userProperties; + cy.login(userProperties.username, userProperties.password, { + path: TopMenu.orderLinesPath, + waiter: OrderLines.waitLoading, + }); + }, + ); + }); + + after(() => { + cy.getAdminToken(); + FileManager.deleteFilesFromDownloadsByMask(fileName); + Users.deleteViaApi(user.userId); + }); + + it( + 'C196751 Export orders based on orders lines search (thunderjet)', + { tags: ['criticalPath', 'thunderjet'] }, + () => { + OrderLines.selectFilterVendorPOL(invoice); + Orders.exportResultsToCsv(); + OrderLines.checkDownloadedFile(); + OrderLines.resetFilters(); + cy.reload(); + OrderLines.selectFilterOngoingPaymentStatus(); + Orders.exportResultsToCsv(); + OrderLines.checkDownloadedFile(); + }, + ); + }); +}); diff --git a/cypress/e2e/orders/pol-export-by-filters.cy.js b/cypress/e2e/orders/pol-export-by-filters.cy.js deleted file mode 100644 index 2659009f40..0000000000 --- a/cypress/e2e/orders/pol-export-by-filters.cy.js +++ /dev/null @@ -1,123 +0,0 @@ -import permissions from '../../support/dictionary/permissions'; -import FinanceHelp from '../../support/fragments/finance/financeHelper'; -import FiscalYears from '../../support/fragments/finance/fiscalYears/fiscalYears'; -import Funds from '../../support/fragments/finance/funds/funds'; -import Ledgers from '../../support/fragments/finance/ledgers/ledgers'; -import Invoices from '../../support/fragments/invoices/invoices'; -import NewInvoice from '../../support/fragments/invoices/newInvoice'; -import NewOrder from '../../support/fragments/orders/newOrder'; -import OrderLines from '../../support/fragments/orders/orderLines'; -import Orders from '../../support/fragments/orders/orders'; -import NewOrganization from '../../support/fragments/organizations/newOrganization'; -import Organizations from '../../support/fragments/organizations/organizations'; -import NewLocation from '../../support/fragments/settings/tenant/locations/newLocation'; -import ServicePoints from '../../support/fragments/settings/tenant/servicePoints/servicePoints'; -import TopMenu from '../../support/fragments/topMenu'; -import Users from '../../support/fragments/users/users'; - -describe('Orders: Export', () => { - const firstFiscalYear = { ...FiscalYears.defaultRolloverFiscalYear }; - const defaultLedger = { ...Ledgers.defaultUiLedger }; - const defaultFund = { ...Funds.defaultUiFund }; - const defaultOrder = { - ...NewOrder.defaultOneTimeOrder, - orderType: 'Ongoing', - ongoing: { isSubscription: false, manualRenewal: false }, - approved: true, - reEncumber: true, - }; - const organization = { ...NewOrganization.defaultUiOrganizations }; - const invoice = { ...NewInvoice.defaultUiInvoice }; - const allocatedQuantity = '100'; - let user; - let firstOrderNumber; - let servicePointId; - let location; - - before(() => { - cy.getAdminToken(); - FiscalYears.createViaApi(firstFiscalYear).then((firstFiscalYearResponse) => { - firstFiscalYear.id = firstFiscalYearResponse.id; - defaultLedger.fiscalYearOneId = firstFiscalYear.id; - Ledgers.createViaApi(defaultLedger).then((ledgerResponse) => { - defaultLedger.id = ledgerResponse.id; - defaultFund.ledgerId = defaultLedger.id; - - Funds.createViaApi(defaultFund).then((fundResponse) => { - defaultFund.id = fundResponse.fund.id; - - cy.loginAsAdmin({ path: TopMenu.fundPath, waiter: Funds.waitLoading }); - FinanceHelp.searchByName(defaultFund.name); - Funds.selectFund(defaultFund.name); - Funds.addBudget(allocatedQuantity); - }); - }); - }); - ServicePoints.getViaApi().then((servicePoint) => { - servicePointId = servicePoint[0].id; - NewLocation.createViaApi(NewLocation.getDefaultLocation(servicePointId)).then((res) => { - location = res; - }); - }); - Organizations.createOrganizationViaApi(organization).then((responseOrganizations) => { - organization.id = responseOrganizations; - invoice.accountingCode = organization.erpCode; - }); - defaultOrder.vendor = organization.name; - cy.visit(TopMenu.ordersPath); - Orders.createOrderForRollover(defaultOrder).then((firstOrderResponse) => { - defaultOrder.id = firstOrderResponse.id; - firstOrderNumber = firstOrderResponse.poNumber; - Orders.checkCreatedOrder(defaultOrder); - OrderLines.addPOLine(); - OrderLines.selectRandomInstanceInTitleLookUP('*', 5); - OrderLines.rolloverPOLineInfoforPhysicalMaterialWithFund( - defaultFund, - '40', - '1', - '40', - location.institutionId, - ); - OrderLines.backToEditingOrder(); - Orders.openOrder(); - cy.visit(TopMenu.invoicesPath); - Invoices.createRolloverInvoice(invoice, organization.name); - Invoices.createInvoiceLineFromPol(firstOrderNumber); - // Need to wait, while data will be loaded - cy.wait(4000); - Invoices.approveInvoice(); - Invoices.payInvoice(); - }); - - cy.createTempUser([permissions.uiExportOrders.gui, permissions.uiOrdersView.gui]).then( - (userProperties) => { - user = userProperties; - cy.login(userProperties.username, userProperties.password, { - path: TopMenu.orderLinesPath, - waiter: OrderLines.waitLoading, - }); - }, - ); - }); - - after(() => { - cy.getAdminToken(); - Users.deleteViaApi(user.userId); - }); - - it( - 'C196751 Export orders based on orders lines search (thunderjet)', - { tags: ['criticalPath', 'thunderjet'] }, - () => { - OrderLines.selectFilterVendorPOL(invoice); - Orders.exportResoultsCSV(); - OrderLines.checkDownloadedFile(); - OrderLines.resetFilters(); - cy.reload(); - OrderLines.selectFilterOngoingPaymentStatus(); - Orders.exportResoultsCSV(); - OrderLines.checkDownloadedFile(); - OrderLines.deleteAllDownloadedFiles(); - }, - ); -}); diff --git a/cypress/support/fragments/orders/modals/exportSettingsModal.js b/cypress/support/fragments/orders/modals/exportSettingsModal.js new file mode 100644 index 0000000000..4ece14936a --- /dev/null +++ b/cypress/support/fragments/orders/modals/exportSettingsModal.js @@ -0,0 +1,79 @@ +import { + Button, + Label, + Modal, + MultiSelect, + MultiSelectMenu, + MultiSelectOption, + RadioButton, + including, + matching, +} from '../../../../../interactors'; +import InteractorsTools from '../../../utils/interactorsTools'; +import OrderStates from '../orderStates'; + +const exportSettingsModal = Modal('Export settings'); +const cancelButton = exportSettingsModal.find(Button('Cancel')); +const exportButton = exportSettingsModal.find(Button('Export')); + +const content = + 'This export could take a few minutes. If you reload or close the page the export will not be completed. Once the file is ready it could take another minute for your browser to finish downloading the file. You can continue to work with orders and order lines in a different browser tab if needed.'; + +const allOrderFieldsRadioButton = RadioButton({ + name: 'orderExport', + ariaLabel: 'Export all order fields', +}); +const selectedOrderFieldsRadioButton = RadioButton({ + name: 'orderExport', + ariaLabel: 'Export selected order fields', +}); +const allOrderLineFieldsRadioButton = RadioButton({ + name: 'lineExport', + ariaLabel: 'Export all line fields', +}); +const selectedOrderLineFieldsRadioButton = RadioButton({ + name: 'lineExport', + ariaLabel: 'Export selected line fields', +}); + +export default { + verifyModalView() { + cy.expect([ + exportSettingsModal.has({ + header: 'Export settings', + }), + exportSettingsModal.has({ + message: including(content), + }), + exportSettingsModal.find(Label('PO fields to export')).exists(), + exportSettingsModal.find(Label('POL fields to export')).exists(), + exportSettingsModal.find(allOrderFieldsRadioButton).exists(), + exportSettingsModal.find(selectedOrderFieldsRadioButton).exists(), + exportSettingsModal.find(allOrderLineFieldsRadioButton).exists(), + exportSettingsModal.find(selectedOrderLineFieldsRadioButton).exists(), + cancelButton.has({ disabled: false, visible: true }), + exportButton.has({ disabled: false, visible: true }), + ]); + }, + selectOrderFieldsToExport(option) { + cy.do([ + selectedOrderFieldsRadioButton.click(), + MultiSelect({ ariaLabelledby: 'selected-po-fields' }).toggle(), + MultiSelectMenu().find(MultiSelectOption(option)).click(), + ]); + }, + clickCancelButton() { + cy.do(cancelButton.click()); + cy.expect(exportSettingsModal.absent()); + }, + clickExportButton({ exportStarted = true } = {}) { + cy.do(exportButton.click()); + cy.expect(exportSettingsModal.absent()); + + if (exportStarted) { + InteractorsTools.checkCalloutMessage( + matching(new RegExp(OrderStates.exportJobStartedSuccessfully)), + ); + } + }, +}; diff --git a/cypress/support/fragments/orders/modals/selectOrganizationModal.js b/cypress/support/fragments/orders/modals/selectOrganizationModal.js new file mode 100644 index 0000000000..94a0f9402f --- /dev/null +++ b/cypress/support/fragments/orders/modals/selectOrganizationModal.js @@ -0,0 +1,20 @@ +import { Button, Modal, SearchField, including } from '../../../../../interactors'; +import SearchHelper from '../../finance/financeHelper'; + +const selectOrganizationModal = Modal(including('Select Organization')); +const searchField = selectOrganizationModal.find(SearchField({ id: 'input-record-search' })); +const searchButton = selectOrganizationModal.find(Button('Search')); +const closeButton = selectOrganizationModal.find(Button('Close')); + +export default { + verifyModalView() { + cy.expect([closeButton.has({ disabled: false, visible: true })]); + }, + findOrganization(organizationName) { + cy.do([searchField.fillIn(organizationName), searchButton.click()]); + SearchHelper.selectFromResultsList(); + }, + closeModal() { + cy.do(closeButton.click()); + }, +}; diff --git a/cypress/support/fragments/orders/orderLines.js b/cypress/support/fragments/orders/orderLines.js index 1607016d3b..4bba23b152 100644 --- a/cypress/support/fragments/orders/orderLines.js +++ b/cypress/support/fragments/orders/orderLines.js @@ -21,9 +21,9 @@ import { Card, TextArea, } from '../../../../interactors'; -import SearchHelper from '../finance/financeHelper'; import getRandomPostfix from '../../utils/stringTools'; import SelectInstanceModal from './modals/selectInstanceModal'; +import SelectOrganizationModal from './modals/selectOrganizationModal'; import { ORDER_FORMAT_NAMES, ACQUISITION_METHOD_NAMES, @@ -37,6 +37,7 @@ import selectLocationModal from './modals/selectLocationModal'; const path = require('path'); +const filtersPane = PaneContent({ id: 'order-lines-filters-pane-content' }); const receivedtitleDetails = PaneContent({ id: 'receiving-results-pane-content' }); const saveAndCloseButton = Button('Save & close'); const cancelButton = Button('Cancel'); @@ -152,7 +153,7 @@ export default { }, resetFilters: () => { - cy.do(Button('Reset all').click()); + cy.do(filtersPane.find(Button('Reset all')).click()); }, checkOrderlineSearchResults: ({ poLineNumber, title } = {}) => { @@ -1389,13 +1390,8 @@ export default { }, selectFilterVendorPOL: (invoice) => { - cy.do([ - buttonFVendorFilter.click(), - Button({ id: 'purchaseOrder.vendor-button' }).click(), - Modal('Select Organization').find(searchField).fillIn(invoice.vendorName), - searchButton.click(), - ]); - SearchHelper.selectFromResultsList(); + cy.do([buttonFVendorFilter.click(), Button({ id: 'purchaseOrder.vendor-button' }).click()]); + SelectOrganizationModal.findOrganization(invoice.vendorName); cy.do(buttonFVendorFilter.click()); }, @@ -1704,7 +1700,7 @@ export default { throw new Error(`No files found in ${downloadsFolder}`); } const fileName = path.basename(files[0]); - const filePath = `${downloadsFolder}\\${fileName}`; + const filePath = `${downloadsFolder}/${fileName}`; cy.readFile(filePath).then((fileContent) => { const fileRows = fileContent.split('\n'); expect(fileRows[0].trim()).to.equal( @@ -1714,10 +1710,6 @@ export default { }); }, - deleteAllDownloadedFiles() { - cy.exec('del cypress\\downloads\\*.csv', { failOnNonZeroExit: false }); - }, - checkCreateInventory() { cy.expect([ physicalResourceDetailsAccordion diff --git a/cypress/support/fragments/orders/orderStates.js b/cypress/support/fragments/orders/orderStates.js index adc2b67cf5..3a554f5a0a 100644 --- a/cypress/support/fragments/orders/orderStates.js +++ b/cypress/support/fragments/orders/orderStates.js @@ -3,4 +3,5 @@ export default { orderOpenedSuccessfully: 'The Purchase order - (?:\\d+) has been successfully opened', orderLineCreatedSuccessfully: 'The purchase order line was successfully created', orderLineUpdatedSuccessfully: 'The purchase order line (?:\\d+\\-\\d+) was successfully updated', + exportJobStartedSuccessfully: 'Export has been started successfully', }; diff --git a/cypress/support/fragments/orders/orders.js b/cypress/support/fragments/orders/orders.js index bb145be998..a642971456 100644 --- a/cypress/support/fragments/orders/orders.js +++ b/cypress/support/fragments/orders/orders.js @@ -29,6 +29,7 @@ import DateTools from '../../utils/dateTools'; import FileManager from '../../utils/fileManager'; import OrderDetails from './orderDetails'; import OrderEditForm from './orderEditForm'; +import ExportSettingsModal from './modals/exportSettingsModal'; import UnopenConfirmationModal from './modals/unopenConfirmationModal'; import OrderLines from './orderLines'; @@ -684,13 +685,18 @@ export default { cy.expect(ordersList.find(HTML(including(orderNumber))).exists()); }, - exportResoultsCSV: () => { - cy.do([ - actionsButton.click(), - Button({ id: 'clickable-export-csv' }).click(), - // Modal('Export settings').find(RadioButton({ ariaLabel: 'Export all line fields' })).click(), - Button('Export').click(), - ]); + clickExportResultsToCsvButton() { + cy.do([actionsButton.click(), Button('Export results (CSV)').click()]); + ExportSettingsModal.verifyModalView(); + + return ExportSettingsModal; + }, + exportResultsToCsv({ confirm = true } = {}) { + this.clickExportResultsToCsvButton(); + + if (confirm) { + ExportSettingsModal.clickExportButton(); + } }, verifySaveCSVQueryFileName(actualName) { diff --git a/cypress/support/fragments/settings/organizations/settingsOrganizations.js b/cypress/support/fragments/settings/organizations/settingsOrganizations.js index 9eb9db34e2..2ddbbaa6ff 100644 --- a/cypress/support/fragments/settings/organizations/settingsOrganizations.js +++ b/cypress/support/fragments/settings/organizations/settingsOrganizations.js @@ -27,6 +27,9 @@ function getEditableListRow(rowNumber) { export default { defaultCategories, defaultTypes, + getDefaultOrganizationType() { + return { id: uuid(), name: `autotest_type_name_${getRandomPostfix()}`, status: 'Active' }; + }, waitLoadingOrganizationSettings: () => { cy.expect(organizationsSettingsSection.exists()); }, @@ -111,4 +114,10 @@ export default { }) .then(({ body }) => body); }, + deleteOrganizationTypeViaApi(organizationTypeId) { + return cy.okapiRequest({ + method: 'DELETE', + path: `organizations-storage/organization-types/${organizationTypeId}`, + }); + }, }; diff --git a/cypress/support/utils/fileManager.js b/cypress/support/utils/fileManager.js index 5c7064b38d..16156974c2 100644 --- a/cypress/support/utils/fileManager.js +++ b/cypress/support/utils/fileManager.js @@ -42,6 +42,14 @@ export default { }); }, + deleteFilesFromDownloadsByMask(...fileNameMasks) { + fileNameMasks.forEach((fileNameMask) => { + this.findDownloadedFilesByMask(fileNameMask).then((fileNames) => { + fileNames?.forEach((fileName) => cy.task('deleteFile', fileName)); + }); + }); + }, + convertCsvToJson(readFileName) { cy.wait(Cypress.env('downloadTimeout')); From a023872d687e1e4bb539acc43f20d4b8ca050a68 Mon Sep 17 00:00:00 2001 From: Daniil Novikau Date: Wed, 6 Dec 2023 13:08:57 +0300 Subject: [PATCH 3/6] [353661] 'Copy' icon is added to PO & POL number --- ...opy-icon-present-on-po-and-pol-panes.cy.js | 78 +++++++++++++++++++ cypress/support/clipboard.js | 19 +++++ cypress/support/e2e.js | 1 + .../support/fragments/orders/orderDetails.js | 32 +++++++- .../fragments/orders/orderLineDetails.js | 26 +++++++ 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 cypress/e2e/orders/copy-icon-present-on-po-and-pol-panes.cy.js create mode 100644 cypress/support/clipboard.js diff --git a/cypress/e2e/orders/copy-icon-present-on-po-and-pol-panes.cy.js b/cypress/e2e/orders/copy-icon-present-on-po-and-pol-panes.cy.js new file mode 100644 index 0000000000..b54ae87d72 --- /dev/null +++ b/cypress/e2e/orders/copy-icon-present-on-po-and-pol-panes.cy.js @@ -0,0 +1,78 @@ +import { Permissions } from '../../support/dictionary'; +import { NewOrder, Orders, BasicOrderLine } from '../../support/fragments/orders'; +import { NewOrganization, Organizations } from '../../support/fragments/organizations'; +import TopMenu from '../../support/fragments/topMenu'; +import Users from '../../support/fragments/users/users'; + +describe('Orders', () => { + const testData = { + organization: NewOrganization.getDefaultOrganization(), + order: {}, + user: {}, + }; + + before('Create test data', () => { + cy.getAdminToken().then(() => { + Organizations.createOrganizationViaApi(testData.organization).then(() => { + testData.order = NewOrder.getDefaultOrder({ vendorId: testData.organization.id }); + testData.orderLine = BasicOrderLine.getDefaultOrderLine(); + + Orders.createOrderWithOrderLineViaApi(testData.order, testData.orderLine).then((order) => { + testData.order = order; + }); + }); + }); + + cy.createTempUser([Permissions.uiOrdersView.gui]).then((userProperties) => { + testData.user = userProperties; + + cy.login(testData.user.username, testData.user.password, { + path: TopMenu.ordersPath, + waiter: Orders.waitLoading, + }); + }); + + cy.stubBrowserPrompt(); + }); + + after('Delete test data', () => { + cy.getAdminToken().then(() => { + Organizations.deleteOrganizationViaApi(testData.organization.id); + Orders.deleteOrderViaApi(testData.order.id); + Users.deleteViaApi(testData.user.userId); + }); + }); + + it( + 'C353661 "Copy" icon is added to PO and POL number (thunderjet) (TaaS)', + { tags: ['extendedPath', 'thunderjet'] }, + () => { + // Click on the record with Order name from precondition + const OrderDetails = Orders.selectOrderByPONumber(testData.order.poNumber); + OrderDetails.checkOrderLinesTableContent([ + { poLineNumber: testData.order.poNumber, poLineTitle: testData.orderLine.title }, + ]); + + // Check "Purchase order" accordion on the "Purchase order" pane + OrderDetails.checkFieldsHasCopyIcon([{ label: 'PO number' }]); + + // Click on the "Copy" icon + OrderDetails.copyOrderNumber(testData.order.poNumber); + + // Check clipboard text + cy.checkBrowserPrompt({ callNumber: 0, promptValue: testData.order.poNumber }); + + // Click on PO line in the "PO lines" tables + const OrderLineDetails = OrderDetails.openPolDetails(testData.orderLine.titleOrPackage); + + // Check "Purchase order line" accordion on the "PO Line details" pane + OrderLineDetails.checkFieldsHasCopyIcon([{ label: 'POL number' }]); + + // Click on the "Copy" icon + OrderLineDetails.copyOrderNumber(`${testData.order.poNumber}-1`); + + // Check clipboard text + cy.checkBrowserPrompt({ callNumber: 1, promptValue: `${testData.order.poNumber}-1` }); + }, + ); +}); diff --git a/cypress/support/clipboard.js b/cypress/support/clipboard.js new file mode 100644 index 0000000000..8dce23ef6d --- /dev/null +++ b/cypress/support/clipboard.js @@ -0,0 +1,19 @@ +// Methods to handle scenarios mentioned in Issue: +// https://github.com/cypress-io/cypress/issues/2739 + +Cypress.Commands.add('stubBrowserPrompt', () => { + cy.window().then((window) => { + cy.stub(window, 'prompt').returns(window.prompt).as('copyToClipboardPrompt'); + }); +}); + +Cypress.Commands.add('checkBrowserPrompt', ({ callNumber, promptValue }) => { + cy.get('@copyToClipboardPrompt').then((prompt) => { + const clipboardText = prompt.args[callNumber][1]; + cy.expect(clipboardText).to.equal(promptValue); + }); +}); + +Cypress.Commands.add('getClipboardText', () => { + cy.window().then((window) => window.navigator.clipboard.readText()); +}); diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index be666d2df5..ccf2c8e82d 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -12,6 +12,7 @@ import './api'; import './login'; import './checkin'; import './checkout'; +import './clipboard'; import './eholdings'; import './inventory'; import './users'; diff --git a/cypress/support/fragments/orders/orderDetails.js b/cypress/support/fragments/orders/orderDetails.js index 7338b468a3..1871065d60 100644 --- a/cypress/support/fragments/orders/orderDetails.js +++ b/cypress/support/fragments/orders/orderDetails.js @@ -26,6 +26,7 @@ import Receivings from '../receiving/receiving'; const orderDetailsPane = Pane({ id: 'order-details' }); const actionsButton = Button('Actions'); +const orderInfoSection = orderDetailsPane.find(Section({ id: 'purchaseOrder' })); const poSummarySection = orderDetailsPane.find(Section({ id: 'POSummary' })); const polListingAccordion = Section({ id: 'POListing' }); @@ -44,6 +45,21 @@ export default { checkOrderStatus(orderStatus) { cy.expect(poSummarySection.find(KeyValue('Workflow status')).has({ value: orderStatus })); }, + checkFieldsConditions(fields = []) { + fields.forEach(({ label, conditions }) => { + cy.expect(orderDetailsPane.find(KeyValue(label)).has(conditions)); + }); + }, + checkFieldsHasCopyIcon(fields = []) { + fields.forEach(({ label }) => { + cy.expect( + orderDetailsPane + .find(KeyValue(label)) + .find(Button({ icon: 'clipboard' })) + .exists(), + ); + }); + }, checkOrderDetails({ summary = [] } = {}) { summary.forEach(({ key, value, checkbox }) => { if (checkbox) { @@ -60,6 +76,16 @@ export default { .click(), ); }, + copyOrderNumber(poNumber) { + cy.do( + orderInfoSection + .find(KeyValue('PO number')) + .find(Button({ icon: 'clipboard' })) + .click(), + ); + + InteractorsTools.checkCalloutMessage(`Successfully copied "${poNumber}" to clipboard.`); + }, openOrder({ orderNumber, confirm = true } = {}) { this.expandActionsDropdown(); cy.do(Button('Open').click()); @@ -158,16 +184,14 @@ export default { if (record.poLineNumber) { cy.expect( polListingAccordion - .find(MultiColumnListRow({ rowIndexInParent: `row-${index}` })) - .find(MultiColumnListCell({ columnIndex: 0 })) + .find(MultiColumnListCell({ row: index, column: 'POL number' })) .has({ content: including(record.poLineNumber) }), ); } if (record.poLineTitle) { cy.expect( polListingAccordion - .find(MultiColumnListRow({ rowIndexInParent: `row-${index}` })) - .find(MultiColumnListCell({ columnIndex: 1 })) + .find(MultiColumnListCell({ row: index, column: 'Title or package name' })) .has({ content: including(record.poLineTitle) }), ); } diff --git a/cypress/support/fragments/orders/orderLineDetails.js b/cypress/support/fragments/orders/orderLineDetails.js index 789173fce1..5cd7ac0938 100644 --- a/cypress/support/fragments/orders/orderLineDetails.js +++ b/cypress/support/fragments/orders/orderLineDetails.js @@ -14,6 +14,7 @@ import OrderLineEditForm from './orderLineEditForm'; import InventoryInstance from '../inventory/inventoryInstance'; import TransactionDetails from '../finance/transactions/transactionDetails'; import ExportDetails from '../exportManager/exportDetails'; +import InteractorsTools from '../../utils/interactorsTools'; const orderLineDetailsSection = Section({ id: 'order-lines-details' }); const paneHeaderOrderLinesDetailes = orderLineDetailsSection.find( @@ -38,6 +39,21 @@ export default { backToOrderDetails() { cy.do(backToOrderButton.click()); }, + checkFieldsConditions(fields = []) { + fields.forEach(({ label, conditions }) => { + cy.expect(orderLineDetailsSection.find(KeyValue(label)).has(conditions)); + }); + }, + checkFieldsHasCopyIcon(fields = []) { + fields.forEach(({ label }) => { + cy.expect( + orderLineDetailsSection + .find(KeyValue(label)) + .find(Button({ icon: 'clipboard' })) + .exists(), + ); + }); + }, checkOrderLineDetails({ purchaseOrderLineInformation = [], vendorDetails, @@ -60,6 +76,16 @@ export default { this.checkLocationsSection(locationDetails); } }, + copyOrderNumber(poNumber) { + cy.do( + purchaseOrderLineSection + .find(KeyValue('POL number')) + .find(Button({ icon: 'clipboard' })) + .click(), + ); + + InteractorsTools.checkCalloutMessage(`Successfully copied "${poNumber}" to clipboard.`); + }, openInventoryItem() { cy.do(itemDetailsSection.find(KeyValue('Title')).find(Link()).click()); From bee41455143524503f59719bc3d021aa0bb45c9b Mon Sep 17 00:00:00 2001 From: Jasurbek Erkinov <99860864+re-jas@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:47:32 +0500 Subject: [PATCH 4/6] added C9318 (#2594) --- .../users/add-and-remove-tags-from-user.cy.js | 43 +++++++++++++++++++ cypress/support/fragments/users/usersCard.js | 37 ++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 cypress/e2e/users/add-and-remove-tags-from-user.cy.js diff --git a/cypress/e2e/users/add-and-remove-tags-from-user.cy.js b/cypress/e2e/users/add-and-remove-tags-from-user.cy.js new file mode 100644 index 0000000000..ad8d8e003c --- /dev/null +++ b/cypress/e2e/users/add-and-remove-tags-from-user.cy.js @@ -0,0 +1,43 @@ +import { getTestEntityValue } from '../../support/utils/stringTools'; +import TopMenu from '../../support/fragments/topMenu'; +import Users from '../../support/fragments/users/users'; +import UsersCard from '../../support/fragments/users/usersCard'; +import UsersSearchPane from '../../support/fragments/users/usersSearchPane'; +import InteractorsTools from '../../support/utils/interactorsTools'; + +describe('Permissions Tags', () => { + let userData; + const newTag = getTestEntityValue('tag'); + + before('Preconditions', () => { + cy.getAdminToken(); + cy.createTempUser().then((userProperties) => { + userData = userProperties; + }); + cy.loginAsAdmin({ + path: TopMenu.usersPath, + waiter: UsersSearchPane.waitLoading, + }); + }); + + after('Deleting created entities', () => { + cy.getAdminToken(); + Users.deleteViaApi(userData.userId); + }); + + it( + 'C9318 Add and remove tags from a user (volaris)', + { tags: ['criticalPath', 'volaris'] }, + () => { + UsersSearchPane.searchByUsername(userData.username); + UsersCard.openTagsPane(); + UsersCard.addTag(newTag); + InteractorsTools.checkCalloutMessage('New tag created'); + UsersCard.verifyTagsNumber('1'); + cy.reload(); + UsersCard.openTagsPane(); + UsersCard.deleteTag(newTag); + UsersCard.verifyTagsNumber('0'); + }, + ); +}); diff --git a/cypress/support/fragments/users/usersCard.js b/cypress/support/fragments/users/usersCard.js index e84abf61d9..7e9391a58b 100644 --- a/cypress/support/fragments/users/usersCard.js +++ b/cypress/support/fragments/users/usersCard.js @@ -17,6 +17,8 @@ import { Badge, ListItem, Modal, + MultiSelect, + MultiSelectOption, } from '../../../../interactors'; import DateTools from '../../utils/dateTools'; import NewNote from '../notes/newNote'; @@ -330,6 +332,41 @@ export default { cy.do(Button('Create block').click()); }, + openTagsPane: () => { + cy.do(Button({ id: 'clickable-show-tags' }).click()); + cy.expect(Pane('Tags').exists()); + cy.wait(2000); + }, + + addTag: (tag) => { + cy.do([ + MultiSelect({ id: 'input-tag' }).fillIn(tag), + MultiSelect({ id: 'input-tag' }).open(), + MultiSelectOption(including(tag)).click(), + ]); + }, + + deleteTag: (tag) => { + cy.do( + MultiSelect({ id: 'input-tag' }) + .find(Button({ icon: 'times' })) + .click(), + ); + cy.expect( + MultiSelect({ id: 'input-tag' }) + .find(HTML(including(tag))) + .absent(), + ); + }, + + verifyTagsNumber: (tagsNum) => { + cy.expect( + Button({ icon: 'tag' }) + .find(HTML(including(tagsNum))) + .exists(), + ); + }, + hasSaveError(errorMessage) { cy.expect(rootSection.find(TextField({ value: errorMessage })).exists()); }, From 0ca4e611604f4412e8c23a419bf3ee7341954c70 Mon Sep 17 00:00:00 2001 From: Yauhen Viazau Date: Wed, 6 Dec 2023 16:01:49 +0500 Subject: [PATCH 5/6] FAT-9725-C422216-added-test (#2597) * updateHoldingRecord method updated * FAT-9725: precondition added * FAT-9725: steps added * FAT-9725: updated methods * FAT-9725: all steps added --- .../facet-search-after-relevance-sort.cy.js | 183 ++++++++++++++++++ .../fragments/inventory/inventoryInstances.js | 51 +++++ .../inventory/inventorySearchAndFilter.js | 16 +- interactors/multi-column-list.js | 1 + 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 cypress/e2e/inventory/search/facet-search-after-relevance-sort.cy.js diff --git a/cypress/e2e/inventory/search/facet-search-after-relevance-sort.cy.js b/cypress/e2e/inventory/search/facet-search-after-relevance-sort.cy.js new file mode 100644 index 0000000000..a3b981925e --- /dev/null +++ b/cypress/e2e/inventory/search/facet-search-after-relevance-sort.cy.js @@ -0,0 +1,183 @@ +import uuid from 'uuid'; +import { Permissions } from '../../../support/dictionary'; +import InventoryInstances from '../../../support/fragments/inventory/inventoryInstances'; +import InventoryInstance from '../../../support/fragments/inventory/inventoryInstance'; +import InventorySearchAndFilter from '../../../support/fragments/inventory/inventorySearchAndFilter'; +import ItemRecordNew from '../../../support/fragments/inventory/item/itemRecordNew'; +import Location from '../../../support/fragments/settings/tenant/locations/newLocation'; +import ServicePoints from '../../../support/fragments/settings/tenant/servicePoints/servicePoints'; +import TopMenu from '../../../support/fragments/topMenu'; +import Users from '../../../support/fragments/users/users'; +import getRandomPostfix, { randomFourDigitNumber } from '../../../support/utils/stringTools'; + +describe('inventory', () => { + describe('Call Number Browse', () => { + const testData = { + searchQuery: `C422216_autotest_instance_${getRandomPostfix()}`, + instanceTag: `inst_tag_${randomFourDigitNumber()}`, + holdingsTag: `hold_tag_${randomFourDigitNumber()}`, + itemTag: `item_tag_${randomFourDigitNumber()}`, + instanceLanguage: 'eng', + titleHeader: 'Title', + relevanceSortOption: 'Relevance', + instanceAccordions: [ + 'Language', + 'Resource Type', + 'Staff suppress', + 'Suppress from discovery', + 'Source', + 'Tags', + ], + holdingsAccordions: ['Holdings type', 'Suppress from discovery', 'Source', 'Tags'], + itemAccordions: ['Item status', 'Suppress from discovery', 'Material type', 'Tags'], + }; + const instances = [ + { + title: `${testData.searchQuery}__1`, + }, + { + title: `${testData.searchQuery}__2`, + }, + { + title: `${testData.searchQuery}__3`, + }, + { + title: `${testData.searchQuery}__4`, + }, + ]; + + before('Create test data', () => { + cy.getAdminToken() + .then(() => { + cy.getInstanceTypes({ limit: 2 }).then((instanceTypes) => { + instances[0].instanceTypeId = instanceTypes[0].id; + }); + cy.getHoldingTypes({ limit: 2 }).then((res) => { + instances[0].holdingTypeId = res[0].id; + }); + cy.getLocations({ limit: 1 }).then((res) => { + instances[0].locationId = res.id; + }); + cy.getLoanTypes({ limit: 1 }).then((res) => { + instances[0].loanTypeId = res[0].id; + instances[0].loanTypeName = res[0].name; + }); + cy.getMaterialTypes({ limit: 1 }).then((res) => { + instances[0].materialTypeId = res.id; + }); + const servicePoint = ServicePoints.getDefaultServicePointWithPickUpLocation(); + instances[0].defaultLocation = Location.getDefaultLocation(servicePoint.id); + Location.createViaApi(instances[0].defaultLocation); + }) + .then(() => { + instances.forEach((instance) => { + InventoryInstances.createFolioInstanceViaApi({ + instance: { + instanceTypeId: instances[0].instanceTypeId, + title: instance.title, + staffSuppress: false, + isBoundWith: false, + languages: [testData.instanceLanguage], + tags: { + tagList: [testData.instanceTag], + }, + }, + holdings: [ + { + holdingsTypeId: instances[0].holdingTypeId, + permanentLocationId: instances[0].defaultLocation.id, + tags: { + tagList: [testData.holdingsTag], + }, + }, + ], + }).then((instanceIds) => { + instance.id = instanceIds.instanceId; + ItemRecordNew.createViaApi({ + holdingsId: instanceIds.holdingIds[0].id, + itemBarcode: uuid(), + materialTypeId: instances[0].materialTypeId, + permanentLoanTypeId: instances[0].loanTypeId, + tags: { + tagList: [testData.itemTag], + }, + }); + }); + }); + }); + + cy.createTempUser([Permissions.inventoryAll.gui]).then((userProperties) => { + testData.userId = userProperties.userId; + cy.login(userProperties.username, userProperties.password, { + path: TopMenu.inventoryPath, + waiter: InventoryInstances.waitContentLoading, + }); + }); + }); + + after('Delete test data', () => { + // without logout, queries from previous run may persist in search during manual re-run + cy.logout(); + cy.getAdminToken(); + Users.deleteViaApi(testData.userId); + instances.forEach((instance) => { + InventoryInstances.deleteInstanceAndItsHoldingsAndItemsViaApi(instance.id); + }); + }); + + it( + 'C422216 Verify that facets options are available after "Relevance" sort was applied to the result list (spitfire)', + { tags: ['criticalPath', 'spitfire'] }, + () => { + InventoryInstance.searchByTitle(testData.searchQuery); + InventorySearchAndFilter.switchToInstance(); + InventoryInstances.checkColumnHeaderSort(testData.titleHeader); + InventoryInstances.checkResultListSortedByColumn(1); + InventoryInstances.clickActionsButton(); + InventoryInstances.actionsSortBy(testData.relevanceSortOption); + InventoryInstances.clickActionsButton(); + InventoryInstances.verifyActionsSortedBy(testData.relevanceSortOption); + testData.instanceAccordions.forEach((accordion) => { + InventorySearchAndFilter.expandAccordion(accordion); + InventorySearchAndFilter.checkOptionsWithCountersExistInAccordion(accordion); + }); + + InventorySearchAndFilter.switchToHoldings(); + InventoryInstances.waitContentLoading(); + InventorySearchAndFilter.verifySearchFieldIsEmpty(); + testData.holdingsAccordions.forEach((accordion) => { + InventorySearchAndFilter.verifyAccordionByNameExpanded(accordion, false); + }); + InventoryInstance.searchByTitle(testData.searchQuery); + InventoryInstances.checkColumnHeaderSort(testData.titleHeader); + InventoryInstances.checkResultListSortedByColumn(1); + InventoryInstances.clickActionsButton(); + InventoryInstances.actionsSortBy(testData.relevanceSortOption); + InventoryInstances.clickActionsButton(); + InventoryInstances.verifyActionsSortedBy(testData.relevanceSortOption); + testData.holdingsAccordions.forEach((accordion) => { + InventorySearchAndFilter.expandAccordion(accordion); + InventorySearchAndFilter.checkOptionsWithCountersExistInAccordion(accordion); + }); + + InventorySearchAndFilter.switchToItem(); + InventoryInstances.waitContentLoading(); + InventorySearchAndFilter.verifySearchFieldIsEmpty(); + testData.itemAccordions.forEach((accordion) => { + InventorySearchAndFilter.verifyAccordionByNameExpanded(accordion, false); + }); + InventoryInstance.searchByTitle(testData.searchQuery); + InventoryInstances.checkColumnHeaderSort(testData.titleHeader); + InventoryInstances.checkResultListSortedByColumn(1); + InventoryInstances.clickActionsButton(); + InventoryInstances.actionsSortBy(testData.relevanceSortOption); + InventoryInstances.clickActionsButton(); + InventoryInstances.verifyActionsSortedBy(testData.relevanceSortOption); + testData.itemAccordions.forEach((accordion) => { + InventorySearchAndFilter.expandAccordion(accordion); + InventorySearchAndFilter.checkOptionsWithCountersExistInAccordion(accordion); + }); + }, + ); + }); +}); diff --git a/cypress/support/fragments/inventory/inventoryInstances.js b/cypress/support/fragments/inventory/inventoryInstances.js index 973f1c049f..23f2ed2628 100644 --- a/cypress/support/fragments/inventory/inventoryInstances.js +++ b/cypress/support/fragments/inventory/inventoryInstances.js @@ -161,6 +161,8 @@ const advSearchItemsOptionsValues = searchItemsOptionsValues .map((option, index) => (index ? option : 'keyword')) .filter((option, index) => index <= 14); +const actionsSortSelect = Select({ dataTestID: 'sort-by-selection' }); + const createInstanceViaAPI = (instanceWithSpecifiedNewId) => cy.okapiRequest({ method: 'POST', path: 'inventory/instances', @@ -1008,4 +1010,53 @@ export default { cy.expect(!checkbox.checked); }); }, + + checkColumnHeaderSort(headerName, isAscending = true) { + const sort = isAscending ? 'ascending' : 'descending'; + cy.expect(inventoriesList.find(MultiColumnListHeader(headerName, { sort })).exists()); + }, + + getResultsListByColumn(columnIndex) { + const cells = []; + + cy.wait(2000); + return cy + .get('div[class^="mclRowContainer--"]') + .find('[data-row-index]') + .each(($row) => { + cy.get(`[class*="mclCell-"]:nth-child(${columnIndex + 1})`, { withinSubject: $row }) + .invoke('text') + .then((cellValue) => { + cells.push(cellValue); + }); + }) + .then(() => cells); + }, + + checkResultListSortedByColumn(columnIndex, isAscending = true) { + this.getResultsListByColumn(columnIndex).then((cells) => { + if (isAscending) { + cy.expect(cells).to.deep.equal(cells.sort((a, b) => a - b)); + } else { + cy.expect(cells).to.deep.equal(cells.sort((a, b) => b - a)); + } + }); + }, + + clickActionsButton() { + cy.do(actionsButton.click()); + cy.expect(actionsSortSelect.exists()); + }, + + actionsSortBy(value) { + cy.do(actionsSortSelect.choose(value)); + // need to wait until content will be sorted + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1000); + cy.expect(actionsSortSelect.absent()); + }, + + verifyActionsSortedBy(value) { + cy.expect(actionsSortSelect.has({ checkedOptionText: value })); + }, }; diff --git a/cypress/support/fragments/inventory/inventorySearchAndFilter.js b/cypress/support/fragments/inventory/inventorySearchAndFilter.js index 11c31984c5..e3751d14a2 100644 --- a/cypress/support/fragments/inventory/inventorySearchAndFilter.js +++ b/cypress/support/fragments/inventory/inventorySearchAndFilter.js @@ -1,4 +1,4 @@ -import { HTML, including } from '@interactors/html'; +import { HTML, including, matching } from '@interactors/html'; import { Accordion, Button, @@ -844,4 +844,18 @@ export default { Section({ id: 'acc02' }).find(KeyValue('Resource title')).has({ value: instanceData.title }), ]); }, + + expandAccordion(accordionName) { + cy.do(paneFilterSection.find(Accordion(accordionName)).clickHeader()); + cy.expect(paneFilterSection.find(Accordion(accordionName)).has({ open: true })); + }, + + checkOptionsWithCountersExistInAccordion(accordionName) { + cy.expect( + paneFilterSection + .find(Accordion(accordionName)) + .find(Checkbox()) + .has({ label: matching(/.{1,}\d{1,}/) }), + ); + }, }; diff --git a/interactors/multi-column-list.js b/interactors/multi-column-list.js index 46c5e2b089..c1e9e0ac8f 100644 --- a/interactors/multi-column-list.js +++ b/interactors/multi-column-list.js @@ -62,6 +62,7 @@ export const MultiColumnListHeader = HTML.extend('multi column list header') content, index: childIndex, id: (el) => el.getAttribute('id'), + sort: (el) => el.getAttribute('aria-sort'), }) .actions({ click: ({ perform }) => perform((el) => el.querySelector('[role=button]').click()), From c7f8bce3f36c15bdb6d70eeeb6dd87f7f821d318 Mon Sep 17 00:00:00 2001 From: Jasurbek Erkinov <99860864+re-jas@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:09:18 +0500 Subject: [PATCH 6/6] added C433 (#2593) --- ...n-checkout-on-the-behalf-of-the-user.cy.js | 95 +++++++++++++++++++ .../check-out-actions/check-out-actions.js | 5 + 2 files changed, 100 insertions(+) create mode 100644 cypress/e2e/users/proxy-user-can-checkout-on-the-behalf-of-the-user.cy.js diff --git a/cypress/e2e/users/proxy-user-can-checkout-on-the-behalf-of-the-user.cy.js b/cypress/e2e/users/proxy-user-can-checkout-on-the-behalf-of-the-user.cy.js new file mode 100644 index 0000000000..2ffe75d1fc --- /dev/null +++ b/cypress/e2e/users/proxy-user-can-checkout-on-the-behalf-of-the-user.cy.js @@ -0,0 +1,95 @@ +import uuid from 'uuid'; +import TopMenu from '../../support/fragments/topMenu'; +import Users from '../../support/fragments/users/users'; +import CheckOutActions from '../../support/fragments/check-out-actions/check-out-actions'; +import Checkout from '../../support/fragments/checkout/checkout'; +import ServicePoints from '../../support/fragments/settings/tenant/servicePoints/servicePoints'; +import Locations from '../../support/fragments/settings/tenant/location-setup/locations'; +import InventoryInstances from '../../support/fragments/inventory/inventoryInstances'; +import CheckInActions from '../../support/fragments/check-in-actions/checkInActions'; +import LoanDetails from '../../support/fragments/users/userDefaultObjects/loanDetails'; + +describe('Users', () => { + const usersData = {}; + const testData = { + folioInstances: InventoryInstances.generateFolioInstances(), + userServicePoint: ServicePoints.getDefaultServicePoint(), + }; + let proxyBody; + + before('Preconditions', () => { + cy.getAdminToken() + .then(() => { + cy.createTempUser().then((sponsorProperties) => { + usersData.userSponsor = sponsorProperties; + cy.getUsers({ limit: 1, query: `"username"="${usersData.userSponsor.username}"` }).then( + (users) => { + usersData.userSponsor.firstName = users[0].personal.firstName; + usersData.userSponsor.middleName = users[0].personal.middleName; + }, + ); + }); + cy.createTempUser().then((proxyProperties) => { + usersData.userProxy = proxyProperties; + }); + }) + .then(() => { + proxyBody = { + userId: usersData.userSponsor.userId, + proxyUserId: usersData.userProxy.userId, + id: uuid(), + requestForSponsor: 'Yes', + notificationsTo: 'Sponsor', + accrueTo: 'Sponsor', + status: 'Active', + }; + cy.createProxyApi(proxyBody); + ServicePoints.createViaApi(testData.userServicePoint); + testData.defaultLocation = Locations.getDefaultLocation({ + servicePointId: testData.userServicePoint.id, + }).location; + Locations.createViaApi(testData.defaultLocation) + .then((location) => { + InventoryInstances.createFolioInstancesViaApi({ + folioInstances: testData.folioInstances, + location, + }); + }) + .then(() => { + testData.itemBarcode = testData.folioInstances[0].barcodes[0]; + testData.itemId = testData.folioInstances[0].itemIds[0]; + }); + }); + cy.loginAsAdmin({ + path: TopMenu.checkOutPath, + waiter: Checkout.waitLoading, + }); + }); + + after('Deleting created entities', () => { + CheckInActions.checkinItemViaApi({ + itemBarcode: testData.itemBarcode, + servicePointId: testData.userServicePoint.id, + checkInDate: new Date().toISOString(), + }); + cy.deleteProxyApi(proxyBody.id); + Users.deleteViaApi(usersData.userSponsor.userId); + Users.deleteViaApi(usersData.userProxy.userId); + }); + + it( + 'C433 Test that proxy user can checkout on the behalf of the user (volaris)', + { tags: ['criticalPath', 'volaris'] }, + () => { + CheckOutActions.checkOutUser(usersData.userProxy.barcode); + CheckOutActions.chooseActingPatron(usersData.userSponsor.lastName); + CheckOutActions.checkOutItem(testData.itemBarcode); + Checkout.verifyResultsInTheRow([testData.itemBarcode]); + CheckOutActions.openLoanDetails(); + LoanDetails.checkKeyValue( + 'Borrower', + `${usersData.userSponsor.lastName}, ${usersData.userSponsor.firstName} ${usersData.userSponsor.middleName}`, + ); + }, + ); +}); diff --git a/cypress/support/fragments/check-out-actions/check-out-actions.js b/cypress/support/fragments/check-out-actions/check-out-actions.js index 2b9cf9f91c..adb3084b8c 100644 --- a/cypress/support/fragments/check-out-actions/check-out-actions.js +++ b/cypress/support/fragments/check-out-actions/check-out-actions.js @@ -11,6 +11,7 @@ import { MultiColumnListCell, PaneContent, Checkbox, + RadioButton, } from '../../../../interactors'; import SelectUser from './selectUser'; @@ -224,4 +225,8 @@ export default { checkNoteModalNotDisplayed: () => { cy.expect(noteModal.absent()); }, + chooseActingPatron: (patron) => { + cy.expect(Modal('Who are you acting as?').exists()); + cy.do([RadioButton(including(patron)).click(), Button('Continue').click()]); + }, };