diff --git a/pydatalab/pydatalab/routes/v0_1/collections.py b/pydatalab/pydatalab/routes/v0_1/collections.py index 37d26f0f2..d0ab54d26 100644 --- a/pydatalab/pydatalab/routes/v0_1/collections.py +++ b/pydatalab/pydatalab/routes/v0_1/collections.py @@ -359,6 +359,8 @@ def add_items_to_collection(collection_id): "relation": None, "type": "collections", "immutable_id": ObjectId(collection["_id"]), + "item_id": None, + "refcode": None, } } }, diff --git a/pydatalab/pydatalab/routes/v0_1/items.py b/pydatalab/pydatalab/routes/v0_1/items.py index ad1890bdc..81d1e8983 100644 --- a/pydatalab/pydatalab/routes/v0_1/items.py +++ b/pydatalab/pydatalab/routes/v0_1/items.py @@ -129,6 +129,7 @@ def get_starting_materials(): "date": 1, "chemform": 1, "name": 1, + "type": 1, "chemical_purity": 1, "supplier": 1, "location": 1, @@ -300,7 +301,8 @@ def search_items(): nresults = request.args.get("nresults", default=100, type=int) types = request.args.get("types", default=None) if isinstance(types, str): - types = types.split(",") # should figure out how to parse as list automatically + # should figure out how to parse as list automatically + types = types.split(",") match_obj = { "$text": {"$search": query}, @@ -428,10 +430,10 @@ def _create_sample( raise RuntimeError("Invalid type") model = ITEM_MODELS[type_] - ## the following code was used previously to explicitely check schema properties. - ## it doesn't seem to be necessary now, with extra = "ignore" turned on in the pydantic models, - ## and it breaks in instances where the models use aliases (e.g., in the starting_material model) - ## so we are taking it out now, but leaving this comment in case it needs to be reverted. + # the following code was used previously to explicitely check schema properties. + # it doesn't seem to be necessary now, with extra = "ignore" turned on in the pydantic models, + # and it breaks in instances where the models use aliases (e.g., in the starting_material model) + # so we are taking it out now, but leaving this comment in case it needs to be reverted. # schema = model.schema() # new_sample = {k: sample_dict[k] for k in schema["properties"] if k in sample_dict} new_sample = sample_dict diff --git a/webapp/cypress.config.ts b/webapp/cypress.config.ts index 1c8625e90..f79ca653b 100644 --- a/webapp/cypress.config.ts +++ b/webapp/cypress.config.ts @@ -6,6 +6,7 @@ export default defineConfig({ baseUrl: "http://localhost:8080", apiUrl: "http://localhost:5001", experimentalMemoryManagement: true, + numTestsKeptInMemory: 0, defaultCommandTimeout: 10000, }, component: { diff --git a/webapp/cypress/e2e/batchSampleFeature.cy.js b/webapp/cypress/e2e/batchSampleFeature.cy.js index c01802dc1..2a4d7cc27 100644 --- a/webapp/cypress/e2e/batchSampleFeature.cy.js +++ b/webapp/cypress/e2e/batchSampleFeature.cy.js @@ -103,9 +103,7 @@ describe("Batch sample creation", () => { cy.verifySample("testB", "this sample has a name"); cy.verifySample("testC"); - cy.deleteSample("testA"); - cy.deleteSample("testB"); - cy.deleteSample("testC"); + cy.deleteSamples(["testA", "testB", "testC"]); }); it("adds two valid samples", () => { @@ -154,6 +152,7 @@ describe("Batch sample creation", () => { }); it("modifies some data in the first sample", () => { + cy.get('[data-testid="search-input"]').type("baseA"); cy.findByText("baseA").click(); cy.findByLabelText("Description").type("this is a description of baseA."); cy.findByText("Add a block").click(); @@ -166,6 +165,7 @@ describe("Batch sample creation", () => { }); it("modifies some data in the second sample", () => { + cy.get('[data-testid="search-input"]').type("baseB"); cy.findByText("baseB").click(); cy.findByLabelText("Description").type("this is a description of baseB."); cy.findByText("Add a block").click(); @@ -437,9 +437,7 @@ describe("Batch sample creation", () => { cy.verifySample("test_2", "testing 1,2"); cy.verifySample("test_3", "testing 1,2,3"); - cy.deleteSample("test_1"); - cy.deleteSample("test_2"); - cy.deleteSample("test_3"); + cy.deleteSamples(["test_1", "test_2", "test_3"]); }); it("uses the template id, name, and date", () => { @@ -462,9 +460,7 @@ describe("Batch sample creation", () => { cy.verifySample("test_6", "this is the test sample #6", "1980-02-01T05:35"); cy.verifySample("test_7", "this is the test sample #7", "1980-02-01T05:35"); - cy.deleteSample("test_5"); - cy.deleteSample("test_6"); - cy.deleteSample("test_7"); + cy.deleteSamples(["test_5", "test_6", "test_7"]); }); it("uses the template id, name, date, copyFrom, and components", () => { @@ -522,6 +518,7 @@ describe("Batch sample creation", () => { cy.get("[data-testid=batch-modal-container]").contains("Close").click(); function checkCreatedSample(item_id) { + cy.get('[data-testid="search-input"]').type(item_id); cy.contains(item_id).click(); cy.contains("this is a description of baseB."); cy.get("#synthesis-information table").contains("component3"); @@ -652,8 +649,7 @@ describe("Batch sample creation", () => { cy.verifySample("test2", "name2"); checkCreatedSample("test1"); checkCreatedSample("test2"); - cy.deleteSample("test1"); - cy.deleteSample("test2"); + cy.deleteSamples(["test1", "test2"]); }); it("checks errors on the row", () => { @@ -832,6 +828,7 @@ describe("Batch cell creation", () => { cy.verifySample("cell_3", "this is the test cell #3", "1980-02-01T23:59"); function checkCreatedCell(item_id) { + cy.get('[data-testid="search-input"]').type(item_id); cy.contains(item_id).click(); cy.get("#pos-electrode-table").contains("comp1"); cy.get("#pos-electrode-table").contains("tagged"); diff --git a/webapp/cypress/e2e/editPage.cy.js b/webapp/cypress/e2e/editPage.cy.js index 404c2a47f..2b08f3f1f 100644 --- a/webapp/cypress/e2e/editPage.cy.js +++ b/webapp/cypress/e2e/editPage.cy.js @@ -35,7 +35,7 @@ describe("Edit Page", () => { it("Adds a valid sample", () => { cy.createSample("editable_sample", "This is a sample name", "1990-01-07T00:00"); - cy.get("tr>td").eq(7).contains(0); // 0 blocks are present + cy.get("tr>td").eq(8).contains(0); // 0 blocks are present }); it("Add some more samples, to use as components", () => { @@ -44,6 +44,7 @@ describe("Edit Page", () => { }); it("Checks editing the sample edit page", () => { + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample").click(); cy.findByLabelText("Name").should("have.value", "This is a sample name"); cy.findByLabelText("Chemical formula").type("NaCoO2", { force: true }); @@ -51,12 +52,13 @@ describe("Edit Page", () => { cy.findByText("Unsaved changes"); cy.get(".fa-save").click(); cy.contains("Unsaved changes").should("not.exist"); - cy.contains("Home").click(); + cy.findByText("Home").click(); + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample"); cy.findByText("This is a sample name"); cy.findByText("1990-01-07"); - cy.get("tbody tr:nth-of-type(3)").contains("NaCoO2"); // sorta check the formula + cy.findByText("NaCoO2"); // sorta check the formula }); it("adds a chemical formula to component1", () => { @@ -69,6 +71,7 @@ describe("Edit Page", () => { }); it("adds some synthesis information", () => { + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample").click(); cy.get("#synthesis-information .vs__search").first().type("component1"); cy.get(".vs__dropdown-menu").contains(".badge", "component1").click(); @@ -122,6 +125,7 @@ describe("Edit Page", () => { }); it("deletes synthesis components and re-adds them", () => { + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample").click(); cy.get("#synthesis-information tbody > tr:nth-of-type(1) .close").click(); cy.get("#synthesis-information tbody > tr").should("have.length", 2); @@ -160,6 +164,7 @@ describe("Edit Page", () => { }); it("tries to add a non-numeric value into quantity", () => { + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample").click(); cy.get("#synthesis-information tbody > tr:nth-of-type(1) td:nth-of-type(2) input").type( "100.001", @@ -196,6 +201,7 @@ describe("Edit Page", () => { }); it("Add some blocks to the sample and checks unsaved warning behavior", () => { + cy.get('[data-testid="search-input"]').type("editable_sample"); cy.findByText("editable_sample").click(); cy.findByLabelText("Name").should("have.value", "This is a sample name"); @@ -237,6 +243,7 @@ describe("Edit Page", () => { cy.contains("Unsaved changes").should("not.exist"); cy.findByText("Home").click(); - cy.get("[data-testid=sample-table] tr:nth-of-type(3) > td:nth-of-type(8)").contains(2); // 2 blocks are present + cy.get('[data-testid="search-input"]').type("editable_sample"); + cy.get("[data-testid=sample-table] tr:nth-of-type(1) > td:nth-of-type(9)").contains(2); // 2 blocks are present }); }); diff --git a/webapp/cypress/e2e/equipment.cy.js b/webapp/cypress/e2e/equipment.cy.js index d74ec3ca5..6a38c1752 100644 --- a/webapp/cypress/e2e/equipment.cy.js +++ b/webapp/cypress/e2e/equipment.cy.js @@ -73,7 +73,10 @@ describe("Equipment table page", () => { it("Attempts to Add an item with the same name", () => { cy.findByText("Add an item").click(); - cy.findByLabelText("ID:").type("test_e3"); + cy.get('[data-testid="create-equipment-form"]').within(() => { + cy.findByText("Add equipment").should("exist"); + cy.findByLabelText("ID:").type("test_e3"); + }); cy.contains("already in use").should("exist"); cy.get(".form-error a").contains("test_e3"); @@ -82,7 +85,19 @@ describe("Equipment table page", () => { }); it("Deletes an item", function () { - cy.get("tr#test_e2 button.close").click(); + cy.get("[data-testid=equipment-table]") + .contains(new RegExp("^" + "test_e2" + "$", "g")) + .parents("tr") + .find("input[type='checkbox']") + .click(); + + cy.get("[data-testid=delete-selected-button]").click(); + + cy.on("window:confirm", (text) => { + expect(text).to.contains("test_e2"); + return true; + }); + cy.contains("test_e2").should("not.exist"); cy.request({ url: `${API_URL}/get-item-data/test_e2`, failOnStatusCode: false }).then( @@ -113,7 +128,7 @@ describe("Equipment table page", () => { describe("Equipment edit page", () => { beforeEach(() => { - cy.visit("/equipment/"); + cy.visit("/equipment"); }); it("Checks the equipment edit page", () => { diff --git a/webapp/cypress/support/commands.js b/webapp/cypress/support/commands.js index 4de1d85ab..2aaf92865 100644 --- a/webapp/cypress/support/commands.js +++ b/webapp/cypress/support/commands.js @@ -68,17 +68,28 @@ Cypress.Commands.add("verifySample", (item_id, name = null, date = null) => { }); }); -Cypress.Commands.add("deleteSample", (item_id) => { - cy.log("search for and delete: " + item_id); - cy.get("[data-testid=sample-table]") - .contains(new RegExp("^" + item_id + "$", "g")) - .parents("tr") - .find("button.close") - .click(); +Cypress.Commands.add("deleteSamples", (items_id) => { + cy.log("search for and delete: " + items_id); + items_id.forEach((item_id) => { + cy.get("[data-testid=sample-table]") + .contains(new RegExp("^" + item_id + "$", "g")) + .parents("tr") + .find("input[type='checkbox']") + .click(); + }); - cy.get("[data-testid=sample-table]") - .contains(new RegExp("^" + item_id + "$", "g")) - .should("not.exist"); + cy.get("[data-testid=delete-selected-button]").click(); + + cy.on("window:confirm", (text) => { + expect(text).to.contains(items_id); + return true; + }); + + items_id.forEach((item_id) => { + cy.get("[data-testid=sample-table]") + .contains(new RegExp("^" + item_id + "$", "g")) + .should("not.exist"); + }); }); Cypress.Commands.add("deleteSampleViaAPI", (item_id) => { @@ -103,6 +114,7 @@ Cypress.Commands.add("searchAndSelectItem", (search_text, selector, clickPlus = Cypress.Commands.add("createEquipment", (item_id, name = null, date = null) => { cy.findByText("Add an item").click(); + cy.get('[data-testid="create-equipment-form"]').within(() => { cy.findByText("Add equipment").should("exist"); cy.findByLabelText("ID:").type(item_id); diff --git a/webapp/src/components/AddToCollectionModal.vue b/webapp/src/components/AddToCollectionModal.vue index 874cedb61..17ab1c56e 100644 --- a/webapp/src/components/AddToCollectionModal.vue +++ b/webapp/src/components/AddToCollectionModal.vue @@ -1,5 +1,5 @@ diff --git a/webapp/src/views/SamplePrime.vue b/webapp/src/views/SamplePrime.vue deleted file mode 100644 index cb4769bec..000000000 --- a/webapp/src/views/SamplePrime.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - - - diff --git a/webapp/src/views/Samples.vue b/webapp/src/views/Samples.vue index c67d00272..2879f3a1c 100644 --- a/webapp/src/views/Samples.vue +++ b/webapp/src/views/Samples.vue @@ -2,52 +2,23 @@
-
-
- - - -
-
- - - diff --git a/webapp/src/views/SamplesNext.vue b/webapp/src/views/SamplesNext.vue deleted file mode 100644 index 0be36955f..000000000 --- a/webapp/src/views/SamplesNext.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - diff --git a/webapp/src/views/StartingMaterials.vue b/webapp/src/views/StartingMaterials.vue index 8208f2b8d..60c4f624d 100644 --- a/webapp/src/views/StartingMaterials.vue +++ b/webapp/src/views/StartingMaterials.vue @@ -1,47 +1,24 @@ diff --git a/webapp/src/views/StartingMaterialsNext.vue b/webapp/src/views/StartingMaterialsNext.vue deleted file mode 100644 index c34976e7c..000000000 --- a/webapp/src/views/StartingMaterialsNext.vue +++ /dev/null @@ -1,22 +0,0 @@ - - -