org.labkey.test.tests.idri.FormulationsTest.java Source code

Java tutorial

Introduction

Here is the source code for org.labkey.test.tests.idri.FormulationsTest.java

Source

/*
 * Copyright (c) 2016-2019 LabKey Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.labkey.test.tests.idri;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.labkey.test.BaseWebDriverTest;
import org.labkey.test.Locator;
import org.labkey.test.TestFileUtils;
import org.labkey.test.categories.Git;
import org.labkey.test.components.ext4.ComboBox;
import org.labkey.test.pages.list.BeginPage;
import org.labkey.test.util.ApiPermissionsHelper;
import org.labkey.test.util.DataRegionTable;
import org.labkey.test.util.Ext4Helper;
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.SampleSetHelper;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static org.junit.Assert.assertEquals;

@Category({ Git.class })
public class FormulationsTest extends BaseWebDriverTest {
    private ApiPermissionsHelper _permissionsHelper = new ApiPermissionsHelper(this);

    private static final String COMPOUNDS_NAME = "Compounds";
    private static final String RAW_MATERIALS_NAME = "Raw Materials";
    private static final String FORMULATIONS_NAME = "Formulations";
    private static final String PROJECT_NAME = "FormulationsTest";

    private static final File LIST_DATA = TestFileUtils.getSampleData("idri/FormulationsTest.lists.zip");

    // Name must be same as what is used as target stability group
    private static final String STABILITY_GROUP = "Stability";

    private static final String COMPOUNDS_HEADER = "Compound Name\tFull Name\tCAS Number\tDensity\tMolecular Weight\tType of Material\n";
    private static final String COMPOUNDS_DATA_1 = "Alum\tAluminum Hydroxide\t21645-51-2\t\t78.0\t1\n"; // adjuvant (rowId 1)
    private static final String COMPOUNDS_DATA_2 = "Squawk\tBean Oil\t21235-51-3\t\t7.0\t3\n"; // oil (rowId 3)
    private static final String COMPOUNDS_DATA_3 = "Cholesterol\tCholesterol\t29935-53-9\t\t123.6\t2\n"; // sterol (rowId 2)
    private static final String COMPOUNDS_DATA_4 = "SPD\tSPD\t2313-23-1\t\t32.23\t4\n"; // buffer (rowId 4)

    private static final String RAWMATERIALS_HEADER = "Identifier\tMaterial Name\tSupplier\tSource\tCatalogue ID\tLot ID\n";
    private static final String RAW_MATERIAL_1 = "IRM-0456";
    private static final String RAW_MATERIAL_2 = "IRM-0016";
    private static final String RAW_MATERIAL_3 = "IRM-0023";
    private static final String RAW_MATERIAL_4 = "IRM-0234";
    private static final String RAWMATERIALS_DATA_1 = RAW_MATERIAL_1
            + "\tAlum\tAlum Supplier\tsynthetic\t\t99999\n";
    private static final String RAWMATERIALS_DATA_2 = RAW_MATERIAL_2 + "\tSquawk\tAlpha\tanimal\t\t123456\n";
    private static final String RAWMATERIALS_DATA_3 = RAW_MATERIAL_3
            + "\tCholesterol\tFresh Supplies\tanimal\t\t314159265\n";
    private static final String RAWMATERIALS_DATA_4 = RAW_MATERIAL_4
            + "\tSPD\tSPD Supplier\tsynthetic\t9123D-AS\t12331-CC\n";

    private static final String FORMULATION = "TD789";
    private static final String PS_FORMULATION = "QH123";

    private static final String CATALOG_DATA_1 = "EM081";
    private static final String GRANT_DATA_1 = "KL9090";

    private static final String PS_ASSAY = "Particle Size";
    private static final String PS_ASSAY_DESC = "IDRI Particle Size Data as provided by Nano and APS machine configurations.";

    private static final String HPLC_ASSAY = "HPLC";
    private static final String PROVISIONAL_HPLC_ASSAY = "pHPLC";
    private static final String PROVISIONAL_HPLC_RUN = "2014_9_19_15_53_20";
    private static final String HPLC_PIPELINE_PATH = TestFileUtils.getLabKeyRoot()
            + "/server/optionalModules/idri/test/sampledata/pHPLC";
    private static final String HPLC_ASSAY_DESC = "IDRI HPLC Assay Data";
    private static final String PROVISIONAL_HPLC_ASSAY_DESC = "IDRI Provisional HPLC Assay Data";

    private static final String VIS_INSPEC_ASSAY = "VisualInspection";
    private static final String VIS_INSPEC_ASSAY_DESC = "Improved IDRI Visual Data.";

    @BeforeClass
    public static void setupProject() {
        FormulationsTest init = (FormulationsTest) getCurrentTest();
        init.doSetup();
    }

    private void doSetup() {
        _userHelper.createUser("ops@labkey.com", false, false);
        enableEmailRecorder();
        _containerHelper.createProject(PROJECT_NAME, "IDRI Formulations");

        goToProjectHome();

        // Create 'Stability' Group
        _permissionsHelper.createPermissionsGroup(STABILITY_GROUP, getCurrentUser());

        // Sample Sets should already exist
        assertElementPresent(Locator.linkWithText(COMPOUNDS_NAME));
        assertElementPresent(Locator.linkWithText(RAW_MATERIALS_NAME));
        assertElementPresent(Locator.linkWithText(FORMULATIONS_NAME));

        setupLists();
        setupCompounds();
        setupRawMaterials();

        // Insert Formulation that the test cases rely on
        // TODO: Separate depended on formulation data from testing of formulation creation
        insertFormulation();
    }

    @Override
    protected void doCleanup(boolean afterTest) {
        _userHelper.deleteUser("ops@labkey.com");
        super.doCleanup(afterTest);
    }

    @Test
    public void testParticleSizeAssay() {
        defineParticleSizeAssay();
        createParticleSizeFormulations();
        uploadParticleSizeData();
    }

    @Test
    public void testHPLCAssay() {
        defineProvisionalHPLCAssay();
        defineHPLCAssay();

        uploadProvisionalHPLCData();
        qualityControlHPLCData();
    }

    @Test
    public void testVisualInspectionAssay() {
        defineVisualInspectionAssay();
        uploadVisualInspectionAssayData();
    }

    @LogMethod
    protected void setupLists() {
        BeginPage listBegin = goToManageLists();
        List<String> formulationsLists = listBegin.getGrid().getColumnDataAsText("Name");
        listBegin = listBegin.importListArchive(LIST_DATA);
        Assert.assertEquals("List archive doesn't match initial Formulations lists", formulationsLists,
                listBegin.getGrid().getColumnDataAsText("Name"));
    }

    @LogMethod
    protected void setupCompounds() {
        goToProjectHome();

        log("Entering compound information");
        clickAndWait(Locator.linkWithText(COMPOUNDS_NAME));

        SampleSetHelper helper = new SampleSetHelper(this);
        helper.bulkImport(
                COMPOUNDS_HEADER + COMPOUNDS_DATA_1 + COMPOUNDS_DATA_2 + COMPOUNDS_DATA_3 + COMPOUNDS_DATA_4);
    }

    @LogMethod
    protected void setupRawMaterials() {
        goToProjectHome();

        log("Entering raw material information");
        clickAndWait(Locator.linkWithText(RAW_MATERIALS_NAME));
        SampleSetHelper helper = new SampleSetHelper(this);
        helper.bulkImport(RAWMATERIALS_HEADER + RAWMATERIALS_DATA_1 + RAWMATERIALS_DATA_2 + RAWMATERIALS_DATA_3
                + RAWMATERIALS_DATA_4);
    }

    @LogMethod
    protected void insertFormulation() {
        String addButton = "Add Another Material";

        goToProjectHome();

        log("Inserting a Formulation");
        clickAndWait(Locator.linkWithText("Sample Sets"));
        clickAndWait(Locator.linkWithText(FORMULATIONS_NAME));
        new DataRegionTable("Material", this).clickInsertNewRow();
        _ext4Helper.waitForMaskToDisappear();

        assertTextPresent("Formulation Type*", "Stability Watch", "Notebook Page*", "Catalog");

        // Describe Formulation
        setFormElement(Locator.name("Batch"), FORMULATION);
        _ext4Helper.waitForMaskToDisappear();
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Type']/.."), "Alum");
        setFormElement(Locator.name("DM"), "8/8/2008");
        setFormElement(Locator.name("batchsize"), "100");
        setFormElement(Locator.name("Comments"), "This might fail.");
        setFormElement(Locator.name("nbpg"), "549-87");
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Catalog']/.."), CATALOG_DATA_1);
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Grant']/.."), GRANT_DATA_1);

        clickButton(addButton, 0);
        _extHelper.selectComboBoxItem(getRawMaterialLocator(0), RAW_MATERIAL_1);
        waitForText(WAIT_FOR_JAVASCRIPT, "%w/vol");
        setFormElement(Locator.name("concentration"), "25.4");

        // Test Duplicate Material
        log("Test Duplicate Material");
        clickButton(addButton, 0);
        _extHelper.selectComboBoxItem(getRawMaterialLocator(1), RAW_MATERIAL_1);
        sleep(2000);
        setFormElements("input", "concentration", new String[] { "25.4", "66.2" });
        clickButton("Create", 0);
        waitForText(WAIT_FOR_JAVASCRIPT, "Duplicate source materials are not allowed.");

        // Test empty combo
        log("Test empty combo");
        clickButton(addButton, 0);
        _extHelper.waitForExt3MaskToDisappear(WAIT_FOR_JAVASCRIPT);
        clickButton("Create", 0);
        _extHelper.waitForExt3MaskToDisappear(WAIT_FOR_JAVASCRIPT);
        waitForText(WAIT_FOR_JAVASCRIPT, "Invalid material");

        // Test empty concentration
        log("Test empty concentration");
        _extHelper.selectComboBoxItem(getRawMaterialLocator(2), RAW_MATERIAL_2);
        waitForText(WAIT_FOR_JAVASCRIPT, "%v/vol");
        clickButton("Create", 0);
        waitForText(WAIT_FOR_JAVASCRIPT, "Invalid material.");

        // Remove duplicate material
        log("Remove duplicate material");
        click(Locator.xpath("//a[text() = 'Remove'][1]")); // remove

        // Add final material
        clickButton(addButton, 0);
        _extHelper.selectComboBoxItem(getRawMaterialLocator(3), RAW_MATERIAL_4);
        waitForText(WAIT_FOR_JAVASCRIPT, "mM");

        // Place on stability watch
        checkCheckbox(Locator.id("stability-check"));

        // Create        
        setFormElements("input", "concentration", new String[] { "25.4", "66.2", "12.91" });
        clickButton("Create", 0);
        waitForText(WAIT_FOR_JAVASCRIPT, "has been created.");

        // Confirm stability email
        _ext4Helper.waitForMaskToDisappear();
        goToModule("Dumbster");
        click(Locator.linkWithText("Formulation added on LabKey"));
        assertElementPresent(Locator.linkWithText(FORMULATION));
    }

    private Locator.XPathLocator getRawMaterialLocator(int index) {
        return Locator.xpath("//div[./input[@id='material" + index + "']]");
    }

    @LogMethod
    protected void createParticleSizeFormulations() {
        goToProjectHome();

        log("Create Formulations used in runs of Particle Size Assay");
        clickAndWait(Locator.linkWithText("Create/Update a Formulation"));
        _extHelper.waitForExt3MaskToDisappear(WAIT_FOR_JAVASCRIPT);

        // Describe Formulation
        setFormElement(Locator.name("Batch"), PS_FORMULATION);
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Type']/.."), "Alum");
        setFormElement(Locator.name("DM"), "9/14/2016");
        setFormElement(Locator.name("batchsize"), "100");
        setFormElement(Locator.name("Comments"), "Lost used for Particle Size");
        setFormElement(Locator.name("nbpg"), "123-33");
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Catalog']/.."), CATALOG_DATA_1);
        _extHelper.selectComboBoxItem(Locator.xpath("//input[@name='Grant']/.."), GRANT_DATA_1);

        clickButton("Add Another Material", 0);
        _extHelper.selectComboBoxItem(getRawMaterialLocator(0), RAW_MATERIAL_2);
        waitForText(WAIT_FOR_JAVASCRIPT, "%v/vol");
        setFormElement(Locator.name("concentration"), "15");

        // Create
        clickButton("Create", 0);
        waitForText(WAIT_FOR_JAVASCRIPT, "has been created.");
    }

    @LogMethod
    protected void defineParticleSizeAssay() {
        goToProjectHome();

        log("Defining Particle Size Assay");
        clickAndWait(Locator.linkWithText("Manage Assays"));
        clickButton("New Assay Design");

        assertTextPresent("Particle Size Data");
        checkCheckbox(Locator.radioButtonByNameAndValue("providerName", "Particle Size"));
        clickButton("Next");

        waitForElement(Locator.xpath("//input[@id='AssayDesignerName']"), WAIT_FOR_JAVASCRIPT);
        setFormElement(Locator.xpath("//input[@id='AssayDesignerName']"), PS_ASSAY);
        setFormElement(Locator.xpath("//textarea[@id='AssayDesignerDescription']"), PS_ASSAY_DESC);
        fireEvent(Locator.xpath("//input[@id='AssayDesignerName']"), SeleniumEvent.blur);

        assertTextPresent(
                // Batch Properties
                "No fields have been defined.",
                // Run Properties
                "IDRIBatchNumber",
                // Result Properties
                "MeasuringTemperature", "meanCountRate", "AnalysisTool");

        clickButton("Save", 0);
        waitForText(10000, "Save successful.");
    }

    @LogMethod
    protected void uploadParticleSizeData() {
        goToProjectHome();

        log("Uploading Particle Size Data");
        clickAndWait(Locator.linkWithText(PS_ASSAY));
        clickButton("Import Data");

        assertTextPresent("pdI value for each entry must be");

        File[] allFiles = TestFileUtils.getSampleData("particleSize")
                .listFiles((dir, name) -> name.matches("^(" + FORMULATION + "|" + PS_FORMULATION + ").xlsx?"));

        for (File file : allFiles) {
            log("uploading " + file.getName());
            setFormElement(Locator.id("upload-run-field-file-button-fileInputEl"), file);
            waitForElement(Locator.linkWithText(file.getName().split("\\.")[0])); // Strip file extension
        }

        log("navigate back to assay batches then runs");
        clickAndWait(Locator.linkWithText("Particle Size Batches"));
        clickAndWait(Locator.linkWithText("view runs"));

        clickAndWait(Locator.linkWithText(FORMULATION));
        DataRegionTable resultsTable = new DataRegionTable("Data", this);

        // validate calculated columns
        Map<String, String> dataRow = resultsTable.getRowDataAsMap(0);
        assertEquals("Unexpected Measuring Temperature", "22", dataRow.get("MeasuringTemperature"));
        assertEquals("Unexpected Storage Temperature", "5C", dataRow.get("StorageTemperature"));
        assertEquals("Unexpected Run/ZAveMean", "114", dataRow.get("Run/ZAveMean"));

        clickAndWait(Locator.linkWithText("view runs"));
        clickAndWait(Locator.linkWithText(PS_FORMULATION));
        resultsTable = new DataRegionTable("Data", this);

        dataRow = resultsTable.getRowDataAsMap(99);
        assertEquals("Unexpected Measuring Temperature", "25", dataRow.get("MeasuringTemperature"));
        assertEquals("Unexpected Storage Temperature", "37C", dataRow.get("StorageTemperature"));
        assertEquals("Unexpected Run/ZAveMean", "66", dataRow.get("Run/ZAveMean"));
    }

    @LogMethod
    protected void defineVisualInspectionAssay() {
        goToProjectHome();

        log("Defining Visual Inspection Assay");
        clickAndWait(Locator.linkWithText("Manage Assays"));
        clickButton("New Assay Design");

        assertTextPresent("Visual Formulation Time-Point Data");
        checkCheckbox(Locator.radioButtonByNameAndValue("providerName", "Visual Inspection"));
        clickButton("Next");

        waitForElement(Locator.xpath("//input[@id='AssayDesignerName']"), WAIT_FOR_JAVASCRIPT);
        setFormElement(Locator.xpath("//input[@id='AssayDesignerName']"), VIS_INSPEC_ASSAY);
        setFormElement(Locator.xpath("//textarea[@id='AssayDesignerDescription']"), VIS_INSPEC_ASSAY_DESC);
        fireEvent(Locator.xpath("//input[@id='AssayDesignerName']"), SeleniumEvent.blur);

        assertTextPresent(
                // Batch Properties
                "No fields have been defined.",
                // Run Properties
                "LotNumber",
                // Result Properties
                "Pass", "Color", "Phase");

        clickButton("Save", 0);
        waitForText(10000, "Save successful.");
    }

    @LogMethod
    protected void uploadVisualInspectionAssayData() {
        goToProjectHome();

        log("Uploading Visual Inspection Data");
        clickAndWait(Locator.linkWithText(VIS_INSPEC_ASSAY));
        clickButton("Import Data");
    }

    @LogMethod
    protected void defineProvisionalHPLCAssay() {
        goToProjectHome();

        log("Defining Provisional HPLC Assay");
        clickAndWait(Locator.linkWithText("Manage Assays"));
        clickButton("New Assay Design");

        assertTextPresent("High performance liquid chromatography assay");
        checkCheckbox(Locator.radioButtonByNameAndValue("providerName", "Provisional HPLC"));
        clickButton("Next");

        waitForElement(Locator.xpath("//input[@id='AssayDesignerName']"), WAIT_FOR_JAVASCRIPT);
        setFormElement(Locator.xpath("//input[@id='AssayDesignerName']"), PROVISIONAL_HPLC_ASSAY);
        setFormElement(Locator.xpath("//textarea[@id='AssayDesignerDescription']"), PROVISIONAL_HPLC_ASSAY_DESC);
        fireEvent(Locator.xpath("//input[@id='AssayDesignerName']"), SeleniumEvent.blur);

        assertTextPresent(
                // Batch Properties
                "No fields have been defined.",
                // Run Properties
                "RunIdentifier", "Method",
                // Result Properties
                "Dilution", "DataFile");

        // Make Runs/Results editable
        checkCheckbox(Locator.checkboxByName("editableRunProperties"));
        checkCheckbox(Locator.checkboxByName("editableResultProperties"));

        clickButton("Save", 0);
        waitForText(10000, "Save successful.");
        clickButton("Save & Close");

        // Set pipeline path
        setPipelineRoot(HPLC_PIPELINE_PATH);
    }

    @LogMethod
    protected void uploadProvisionalHPLCData() {
        beginAt("/" + getProjectName() + "/idri-mockHPLCWatch.view");
        waitForText("Ready to Load");
        click(Locator.tagWithClass("input", "idri-run-btn"));
        waitForText("Test Run Upload Complete");
        sleep(1500);
    }

    @LogMethod
    protected void qualityControlHPLCData() {
        String standardName = "LGCTest";
        String[] standards = { "LGC20371", "LGC40060", "LGC60342", "LGC80021", "LGC10030" };
        String[] concs = { "20", "40", "60", "80", "100" };
        String left = "12";
        String right = "15";
        String base = "40";

        String[] samples = { "QD123-11", "QD123-24", "QD123-31" };
        String sleft = "14.5";
        String sright = "16";
        String sbase = "45";

        //
        // Start QC Process
        //
        goToProjectHome();

        click(Locator.linkWithText(PROVISIONAL_HPLC_ASSAY));
        waitForElement(Locator.linkWithText(PROVISIONAL_HPLC_RUN));

        DataRegionTable runs = new DataRegionTable("Runs", this);
        runs.checkCheckbox(0);
        clickButton("QC Selected Run");

        log("Start the Qualitative Analysis");
        waitForElement(Locator.tagWithClass("div", "x4-grid-cell-inner").withText(samples[0]));
        clickButton("Define Standards", 0);
        sleep(1000);
        waitForElement(Locator.tagWithClass("div", "x4-grid-cell-inner").withText(standards[0]));

        for (String std : standards) {
            // check in concentration order
            _ext4Helper.checkGridRowCheckbox(std);
        }

        for (int i = 0; i < standards.length; i++) {
            Locator.XPathLocator runRow = Locator.tagWithAttribute("tr", "modelname", standards[i]);
            setFormElement(runRow.append(Locator.input("concentration")), concs[i]);
            if (i == 0) {
                setFormElement(runRow.append(Locator.input("xleft")), left);
                setFormElement(runRow.append(Locator.input("xright")), right);
                setFormElement(runRow.append(Locator.input("base")), base);
            }
        }

        click(Locator.button("C").index(0));
        waitForText("to all other selections?");
        clickButton("Yes", 0);

        // ensure the copy gets all the way to the last row
        waitForElement(Locator.tagWithAttribute("tr", "modelname", standards[standards.length - 1])
                .append(Locator.input("base").withAttribute("value", base)));

        setFormElement(Locator.input("standardname"), standardName);
        clickButton("Calibration Curve", 0);
        waitForElement(Locator.id("standardrsquared-inputEl").containing("0.99"));

        clickButton("Save", 0);
        waitForElement(Locator.tagWithClass("div", "x4-grid-cell-inner").withText(standardName));

        log("Quality Control Samples");
        clickButton("Return to Samples", 0);
        waitForElement(Locator.tagWithClass("div", "x4-grid-cell-inner").withText(samples[0]));

        for (String samp : samples) {
            _ext4Helper.checkGridRowCheckbox(samp);
        }

        clickButton("Start QC", 0);
        waitForElementToDisappear(Locator.id("sampleinputs").notHidden());

        new ComboBox.ComboBoxFinder(getDriver()).withIdPrefix("compoundlist").find(getDriver())
                .selectComboBoxItem("Squawk");
        new ComboBox.ComboBoxFinder(getDriver()).withIdPrefix("standardslist").find(getDriver())
                .selectComboBoxItem(standardName);
        new ComboBox.ComboBoxFinder(getDriver()).withIdPrefix("formulationlist").find(getDriver())
                .selectComboBoxItem(FORMULATION);
        new ComboBox.ComboBoxFinder(getDriver()).withIdPrefix("temperaturelist").find(getDriver())
                .selectComboBoxItem("5");
        new ComboBox.ComboBoxFinder(getDriver()).withIdPrefix("timelist").find(getDriver())
                .selectComboBoxItem("T=0");

        Locator.XPathLocator firstSampleRow = Locator.tagWithAttribute("tr", "modelname", samples[0]);
        setFormElement(firstSampleRow.append(Locator.input("xleft")), sleft);
        setFormElement(firstSampleRow.append(Locator.input("xright")), sright);
        setFormElement(firstSampleRow.append(Locator.input("base")), sbase);
        click(Locator.button("C").index(0));
        waitForText("to all other selections?");
        clickButton("Yes", 0);

        // ensure the copy gets all the way to the last row
        waitForElement(Locator.tagWithAttribute("tr", "modelname", samples[samples.length - 1])
                .append(Locator.input("base").withAttribute("value", sbase)));

        clickButton("Calculate", 0);
        shortWait().until(ExpectedConditions.textToBePresentInElementValue(By.name("avgconc"), "-24.")); // -24.76
        shortWait().until(ExpectedConditions.textToBePresentInElementValue(By.name("stddev"), "10.")); // 10.69

        waitForSampleFormValidation();
        waitAndClick(Ext4Helper.Locators.ext4Button("Submit Analysis").enabled());
        waitForText("successfully");
        waitForElementToDisappear(Ext4Helper.Locators.ext4Button("Submit Analysis").enabled());
    }

    private void waitForSampleFormValidation() {
        shortWait().until(new Function<WebDriver, Boolean>() {
            @Override
            public Boolean apply(WebDriver webDriver) {
                return (Boolean) executeScript("return Ext4.getCmp('sampleform').isValid();");
            }

            @Override
            public String toString() {
                return "sample form to be valid";
            }
        });
    }

    @LogMethod
    protected void defineHPLCAssay() {
        goToProjectHome();

        log("Defining HPLC Assay");
        clickAndWait(Locator.linkWithText("Manage Assays"));
        clickButton("New Assay Design");

        assertTextPresent("High performance liquid chromatography assay");
        checkCheckbox(Locator.radioButtonByNameAndValue("providerName", "HPLC"));
        clickButton("Next");

        waitForElement(Locator.xpath("//input[@id='AssayDesignerName']"), WAIT_FOR_JAVASCRIPT);
        setFormElement(Locator.xpath("//input[@id='AssayDesignerName']"), HPLC_ASSAY);
        setFormElement(Locator.xpath("//textarea[@id='AssayDesignerDescription']"), HPLC_ASSAY_DESC);
        fireEvent(Locator.xpath("//input[@id='AssayDesignerName']"), SeleniumEvent.blur);

        assertTextPresent(
                // Batch Properties
                "No fields have been defined.",
                // Run Properties
                "LotNumber", "CompoundNumber",
                // Result Properties
                "Dilution", "FilePath", "Concentration");

        // Make Runs/Results editable
        checkCheckbox(Locator.checkboxByName("editableRunProperties"));
        checkCheckbox(Locator.checkboxByName("editableResultProperties"));

        clickButton("Save", 0);
        waitForText(10000, "Save successful.");
        clickButton("Save & Close");
    }

    @Override
    public List<String> getAssociatedModules() {
        return Collections.singletonList("idri");
    }

    @Override
    protected String getProjectName() {
        return PROJECT_NAME;
    }

    @Override
    public BrowserType bestBrowser() {
        return BrowserType.CHROME;
    }
}