From bae05eb7cd8fbab77f878c7463d76231200c9d88 Mon Sep 17 00:00:00 2001
From: anttil <anttil>
Date: Tue, 11 Sep 2012 15:56:20 +0000
Subject: [PATCH] SWE-2 / SP-263: Creation of projects and experiments.
 Deletion of samples, sample types.

SVN: 26599
---
 .../web/client/application/ui/SpaceGrid.java  |   2 +
 .../entity_type/AbstractEntityTypeGrid.java   |   3 +-
 .../application/ui/project/ProjectGrid.java   |   3 +
 .../ui/property_type/PropertyTypeGrid.java    |   7 +-
 ...rtyTypeListDeletionConfirmationDialog.java |   1 +
 .../ui/vocabulary/VocabularyGrid.java         |   8 +-
 ...abularyListDeletionConfirmationDialog.java |   1 +
 .../cisd/openbis/uitest/ExperimentTest.java   |  53 +++++++
 .../openbis/uitest/ExperimentTypeTest.java    |  23 +++
 .../cisd/openbis/uitest/ManualTest.java       | 137 ++++++++++++++++++
 .../cisd/openbis/uitest/ProjectTest.java      |  23 +++
 .../uitest/infra/ApplicationRunner.java       |  58 ++++++++
 .../cisd/openbis/uitest/infra/PageProxy.java  |   2 +-
 .../openbis/uitest/infra/SeleniumTest.java    |  40 +++++
 .../matcher/CellContainsLinkMatcher.java      |   2 +-
 .../cisd/openbis/uitest/page/BrowserPage.java |  81 +++++------
 .../cisd/openbis/uitest/page/Cell.java        |  15 +-
 .../page/dialog/AddExperimentTypeDialog.java  |  59 ++++++++
 .../uitest/page/fragment/VarcharInput.java    |  35 +++++
 .../openbis/uitest/page/menu/AdminMenu.java   |  11 ++
 .../openbis/uitest/page/menu/BrowseMenu.java  |  11 ++
 .../openbis/uitest/page/menu/NewMenu.java     |  20 +++
 .../page/tab/ExperimentTypeBrowser.java       |  75 ++++++++++
 .../uitest/page/tab/ProjectBrowser.java       |  62 ++++++++
 .../tab/PropertyTypeAssignmentBrowser.java    |  13 +-
 .../uitest/page/tab/PropertyTypeBrowser.java  |  13 +-
 .../uitest/page/tab/RegisterExperiment.java   |  97 +++++++++++++
 .../uitest/page/tab/RegisterProject.java      |  66 +++++++++
 .../uitest/page/tab/RegisterSample.java       |   6 +-
 .../page/tab/RoleAssignmentBrowser.java       |   7 +
 .../uitest/page/tab/SampleBrowser.java        |  14 +-
 .../uitest/page/tab/SampleTypeBrowser.java    |  16 +-
 .../openbis/uitest/page/tab/SpaceBrowser.java |  13 +-
 .../uitest/page/tab/VocabularyBrowser.java    |  13 +-
 .../cisd/openbis/uitest/type/Experiment.java  |  16 +-
 .../uitest/type/ExperimentBuilder.java        |  94 ++++++++++++
 .../openbis/uitest/type/ExperimentType.java   |  39 ++++-
 .../uitest/type/ExperimentTypeBuilder.java    |  53 +++++++
 .../cisd/openbis/uitest/type/Project.java     |   2 +-
 .../openbis/uitest/type/ProjectBuilder.java   |  66 +++++++++
 .../uitest/type/PropertyTypeBuilder.java      |  12 ++
 .../openbis/uitest/type/SampleBuilder.java    |  12 ++
 .../uitest/type/SampleTypeBuilder.java        |  12 ++
 .../openbis/uitest/type/SpaceBuilder.java     |  10 +-
 .../uitest/type/VocabularyBuilder.java        |   6 +
 45 files changed, 1233 insertions(+), 79 deletions(-)
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTest.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTypeTest.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ManualTest.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ProjectTest.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/dialog/AddExperimentTypeDialog.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/fragment/VarcharInput.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterExperiment.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterProject.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentBuilder.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentTypeBuilder.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ProjectBuilder.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/SpaceGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/SpaceGrid.java
index 20871656012..8404eef66b3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/SpaceGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/SpaceGrid.java
@@ -136,6 +136,7 @@ public class SpaceGrid extends TypedTableGrid<Space>
                                             groups, createRefreshCallback(invoker));
                                 }
                             });
+        deleteButton.setId(DELETE_BUTTON_ID);
         addButton(deleteButton);
         allowMultipleSelection(); // we allow deletion of multiple projects
 
@@ -224,6 +225,7 @@ public class SpaceGrid extends TypedTableGrid<Space>
         {
             super(viewContext, data, callback);
             this.viewContext = viewContext;
+            this.setId("deletion-confirmation-dialog");
         }
 
         @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/entity_type/AbstractEntityTypeGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/entity_type/AbstractEntityTypeGrid.java
index 0749a4762ff..118386b2a81 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/entity_type/AbstractEntityTypeGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/entity_type/AbstractEntityTypeGrid.java
@@ -92,7 +92,7 @@ abstract public class AbstractEntityTypeGrid<T extends EntityType> extends Typed
                             createRegisterEntityTypeDialog(entityKind).show();
                         }
                     });
-        button.setId("add-entity-type");
+        button.setId("add-entity-type-" + this.getClass().getName());
         addButton(button);
 
         Button editButton =
@@ -157,6 +157,7 @@ abstract public class AbstractEntityTypeGrid<T extends EntityType> extends Typed
                                                 viewContext));
                                     }
                                 };
+                    confirmationDialog.setId("deletion-confirmation-dialog");
                     confirmationDialog.show();
                 }
             });
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/project/ProjectGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/project/ProjectGrid.java
index 527ae07b3bc..ac006286a05 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/project/ProjectGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/project/ProjectGrid.java
@@ -77,6 +77,8 @@ public class ProjectGrid extends TypedTableGrid<Project>
 
     public static final String EDIT_BUTTON_ID = BROWSER_ID + "-edit";
 
+    public static final String DELETE_BUTTON_ID = BROWSER_ID + "-delete";
+
     public static IDisposableComponent create(
             final IViewContext<ICommonClientServiceAsync> viewContext)
     {
@@ -158,6 +160,7 @@ public class ProjectGrid extends TypedTableGrid<Project>
                                             projects, createRefreshCallback(invoker));
                                 }
                             });
+        deleteButton.setId(DELETE_BUTTON_ID);
         addButton(deleteButton);
         allowMultipleSelection(); // we allow deletion of multiple projects
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeGrid.java
index 405f5db65e6..2378d1c05ce 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeGrid.java
@@ -129,7 +129,7 @@ public class PropertyTypeGrid extends TypedTableGrid<PropertyType>
                         }
                     }));
 
-        addButton(createSelectedItemsButton(viewContext.getMessage(Dict.BUTTON_DELETE),
+        Button deleteButton = createSelectedItemsButton(viewContext.getMessage(Dict.BUTTON_DELETE),
                 new AbstractCreateDialogListener()
                     {
 
@@ -158,7 +158,10 @@ public class PropertyTypeGrid extends TypedTableGrid<PropertyType>
                             }
                             return true;
                         }
-                    }));
+                    });
+        deleteButton.setId(GRID_ID + "-delete-button");
+        addButton(deleteButton);
+
         allowMultipleSelection(); // we allow deletion of multiple property types
 
         addEntityOperationsSeparator();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeListDeletionConfirmationDialog.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeListDeletionConfirmationDialog.java
index ba463f53e4d..bc852a19ae0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeListDeletionConfirmationDialog.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeListDeletionConfirmationDialog.java
@@ -41,6 +41,7 @@ public final class PropertyTypeListDeletionConfirmationDialog extends
             AbstractAsyncCallback<Void> callback)
     {
         super(viewContext, propertyTypes, callback);
+        this.setId("deletion-confirmation-dialog");
         this.viewContext = viewContext;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyGrid.java
index 37c8af18f2e..d5d7f2b385a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyGrid.java
@@ -81,6 +81,8 @@ public class VocabularyGrid extends TypedTableGrid<Vocabulary>
 
     public static final String ADD_BUTTON_ID = BROWSER_ID + "_add-button";
 
+    public static final String DELETE_BUTTON_ID = BROWSER_ID + "_delete-button";
+
     private final IDelegatedAction postEditionCallback;
 
     public static IDisposableComponent create(
@@ -240,7 +242,7 @@ public class VocabularyGrid extends TypedTableGrid<Vocabulary>
 
                     }));
 
-        addButton(createSelectedItemsButton(viewContext.getMessage(Dict.BUTTON_DELETE),
+        Button deleteButton = createSelectedItemsButton(viewContext.getMessage(Dict.BUTTON_DELETE),
                 new AbstractCreateDialogListener()
                     {
 
@@ -268,7 +270,9 @@ public class VocabularyGrid extends TypedTableGrid<Vocabulary>
                             }
                             return true;
                         }
-                    }));
+                    });
+        deleteButton.setId(DELETE_BUTTON_ID);
+        addButton(deleteButton);
 
         allowMultipleSelection(); // we allow deletion of multiple vocabularies
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyListDeletionConfirmationDialog.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyListDeletionConfirmationDialog.java
index c591e6d1cad..024f79102ca 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyListDeletionConfirmationDialog.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyListDeletionConfirmationDialog.java
@@ -41,6 +41,7 @@ public final class VocabularyListDeletionConfirmationDialog extends
             AbstractAsyncCallback<Void> callback)
     {
         super(viewContext, vocabularies, callback);
+        this.setId("deletion-confirmation-dialog");
         this.localViewContext = viewContext;
     }
 
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTest.java
new file mode 100644
index 00000000000..12d47ac9bd9
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.uitest.infra.SeleniumTest;
+import ch.systemsx.cisd.openbis.uitest.type.Experiment;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
+import ch.systemsx.cisd.openbis.uitest.type.Sample;
+import ch.systemsx.cisd.openbis.uitest.type.Space;
+
+/**
+ * @author anttil
+ */
+@Test(groups =
+    { "login-admin" })
+public class ExperimentTest extends SeleniumTest
+{
+
+    @Test
+    public void creatingExperimentWithSampleChangesTheSample() throws Exception
+    {
+        Space space = create(aSpace());
+        Project project = create(aProject().in(space));
+        Sample sample = create(aSample().in(space));
+
+        Experiment experiment = create(anExperiment().in(project).withSamples(sample));
+
+        assertThat(sampleBrowser().dataOf(sample).get("Experiment").getText(),
+                is(experiment.getCode().toUpperCase()));
+        assertThat(sampleBrowser().dataOf(sample).get("Project").getText(),
+                is(project.getCode().toUpperCase()));
+
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTypeTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTypeTest.java
new file mode 100644
index 00000000000..4651c81dec0
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ExperimentTypeTest.java
@@ -0,0 +1,23 @@
+package ch.systemsx.cisd.openbis.uitest;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.uitest.infra.SeleniumTest;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+
+@Test(groups =
+    { "login-admin" })
+public class ExperimentTypeTest extends SeleniumTest
+{
+
+    @Test
+    public void newExperimentTypeIsListedInExperimentTypeBrowser() throws Exception
+    {
+        ExperimentType type = create(anExperimentType());
+
+        assertThat(experimentTypeBrowser(), lists(type));
+    }
+
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ManualTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ManualTest.java
new file mode 100644
index 00000000000..37eec512a32
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ManualTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.uitest.infra.SeleniumTest;
+import ch.systemsx.cisd.openbis.uitest.page.dialog.AddSampleTypeDialog;
+import ch.systemsx.cisd.openbis.uitest.page.tab.RoleAssignmentBrowser;
+import ch.systemsx.cisd.openbis.uitest.type.Experiment;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
+import ch.systemsx.cisd.openbis.uitest.type.PropertyType;
+import ch.systemsx.cisd.openbis.uitest.type.Sample;
+import ch.systemsx.cisd.openbis.uitest.type.SampleType;
+import ch.systemsx.cisd.openbis.uitest.type.Space;
+import ch.systemsx.cisd.openbis.uitest.type.Vocabulary;
+
+/**
+ * @author anttil
+ */
+@Test(groups =
+    { "login-admin" })
+public class ManualTest extends SeleniumTest
+{
+
+    @Test(enabled = false)
+    public void basic()
+    {
+        // 0) Cleanup
+        spaceBrowser().deleteIfExists("Code", "sprint-test");
+        sampleTypeBrowser().deleteIfExists("Code", "sprint_test");
+        propertyTypeBrowser().deleteIfExists("Code", "sprint-test.text");
+        propertyTypeBrowser().deleteIfExists("Code", "sprint-test.real");
+        propertyTypeBrowser().deleteIfExists("Code", "sprint-test.animal");
+        vocabularyBrowser().deleteIfExists("Code", "sprint-test-animal");
+
+        // 1) Login and authorization
+        openbis.browseToRoleAssignmentBrowser();
+        assertThat(browser(), isShowing(RoleAssignmentBrowser.class));
+
+        // 2) Space
+        Space space = create(aSpace().withCode("sprint-test"));
+        assertThat(spaceBrowser(), lists(space));
+
+        // 3) Sample types and properties
+        create(aSampleType().withCode("sprint test"));
+        assertThat(browser(), isShowing(AddSampleTypeDialog.class));
+        get(AddSampleTypeDialog.class).cancel();
+
+        SampleType sampleType =
+                create(aSampleType()
+                        .withCode("sprint_test")
+                        .thatIsNotListable()
+                        .thatShowsContainer()
+                        .thatShowsParents());
+        assertThat(sampleTypeBrowser(), lists(sampleType));
+        assertThat(sampleBrowser(), doesNotShowInToolBar(sampleType));
+
+        perform(anUpdateOf(sampleType).settingItListable());
+        assertThat(sampleBrowser(), showsInToolBar(sampleType));
+
+        Vocabulary vocabulary =
+                create(aVocabulary()
+                        .withCode("SPRINT-TEST-ANIMAL")
+                        .withTerms("mouse", "fly", "tiger")
+                        .withUrl("http://www.ask.com/web?q=${term}"));
+
+        PropertyType varcharPropertyType =
+                create(aVarcharPropertyType()
+                        .withCode("SPRINT-TEST.TEXT")
+                        .withLabel("Sprint Test Text")
+                        .withDescription("some text"));
+
+        PropertyType realPropertyType =
+                create(aRealPropertyType()
+                        .withCode("SPRINT-TEST.REAL")
+                        .withLabel("Sprint Test Real")
+                        .withDescription("some text"));
+
+        PropertyType animalPropertyType =
+                create(aVocabularyPropertyType(vocabulary)
+                        .withCode("SPRINT-TEST.ANIMAL")
+                        .withLabel("Sprint Test Animal")
+                        .withDescription("some text"));
+
+        create(aSamplePropertyTypeAssignment()
+                .with(sampleType)
+                .thatIsMandatory()
+                .with(varcharPropertyType));
+        create(aSamplePropertyTypeAssignment().with(sampleType).with(animalPropertyType));
+
+        assertThat(sampleRegistrationPageFor(sampleType),
+                hasInputsForProperties(varcharPropertyType, animalPropertyType));
+
+        // 4) Sample
+        Sample sample =
+                create(aSample().ofType(sampleType)
+                        .withCode("SPRINT1")
+                        .in(space)
+                        .withProperty(varcharPropertyType, "some text")
+                        .withProperty(animalPropertyType, "mouse"));
+
+        assertThat(sampleBrowser(), lists(sample));
+        assertThat(sampleBrowser().dataOf(sample).get(animalPropertyType.getLabel()),
+                containsLink("MOUSE", "http://www.ask.com/web?q=MOUSE"));
+
+        // 5) Project and experiment
+        Project project = create(aProject().withCode("P1").in(space));
+        ExperimentType experimentType = create(anExperimentType().withCode("SPRINT_TEST"));
+
+        Experiment experiment =
+                create(anExperiment().ofType(experimentType).in(project).withCode("exp1")
+                        .withSamples(sample));
+        assertThat(sampleBrowser().dataOf(sample).get("Experiment").getText(),
+                is(experiment.getCode().toUpperCase()));
+        assertThat(sampleBrowser().dataOf(sample).get("Project").getText(),
+                is(project.getCode().toUpperCase()));
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ProjectTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ProjectTest.java
new file mode 100644
index 00000000000..10d2c234417
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/ProjectTest.java
@@ -0,0 +1,23 @@
+package ch.systemsx.cisd.openbis.uitest;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.uitest.infra.SeleniumTest;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
+
+@Test(groups =
+    { "login-admin" })
+public class ProjectTest extends SeleniumTest
+{
+
+    @Test
+    public void newProjectIsListedInProjectBrowser() throws Exception
+    {
+        Project project = create(aProject());
+
+        assertThat(projectBrowser(), lists(project));
+    }
+
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/ApplicationRunner.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/ApplicationRunner.java
index 4a727960c54..69ff48b72fe 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/ApplicationRunner.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/ApplicationRunner.java
@@ -18,20 +18,28 @@ package ch.systemsx.cisd.openbis.uitest.infra;
 
 import ch.systemsx.cisd.openbis.uitest.page.LoginPage;
 import ch.systemsx.cisd.openbis.uitest.page.NavigationPage;
+import ch.systemsx.cisd.openbis.uitest.page.dialog.AddExperimentTypeDialog;
 import ch.systemsx.cisd.openbis.uitest.page.dialog.AddSampleTypeDialog;
 import ch.systemsx.cisd.openbis.uitest.page.dialog.AddSpaceDialog;
 import ch.systemsx.cisd.openbis.uitest.page.dialog.AddVocabularyDialog;
 import ch.systemsx.cisd.openbis.uitest.page.dialog.EditSampleTypeDialog;
 import ch.systemsx.cisd.openbis.uitest.page.tab.AddPropertyType;
 import ch.systemsx.cisd.openbis.uitest.page.tab.AssignSamplePropertyType;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ProjectBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeAssignmentBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeBrowser;
+import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterExperiment;
+import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterProject;
 import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterSample;
 import ch.systemsx.cisd.openbis.uitest.page.tab.RoleAssignmentBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SampleBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SampleTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SpaceBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.VocabularyBrowser;
+import ch.systemsx.cisd.openbis.uitest.type.Experiment;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyType;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyTypeAssignment;
 import ch.systemsx.cisd.openbis.uitest.type.Sample;
@@ -60,6 +68,14 @@ public class ApplicationRunner
         return space;
     }
 
+    public Project create(Project project)
+    {
+        RegisterProject register = browseToRegisterProject();
+        register.fillWith(project);
+        register.save();
+        return project;
+    }
+
     public SampleType create(SampleType sampleType)
     {
         AddSampleTypeDialog dialog = browseToAddSampleTypeDialog();
@@ -68,6 +84,14 @@ public class ApplicationRunner
         return sampleType;
     }
 
+    public ExperimentType create(ExperimentType experimentType)
+    {
+        AddExperimentTypeDialog dialog = browseToAddExperimentTypeDialog();
+        dialog.fillWith(experimentType);
+        dialog.save();
+        return experimentType;
+    }
+
     public Vocabulary create(Vocabulary vocabulary)
     {
         AddVocabularyDialog dialog = browseToAddVocabularyDialog();
@@ -93,6 +117,15 @@ public class ApplicationRunner
         return sample;
     }
 
+    public Experiment create(Experiment experiment)
+    {
+        RegisterExperiment register = browseToRegisterExperiment();
+        register.selectExperimentType(experiment.getType());
+        register.fillWith(experiment);
+        register.save();
+        return experiment;
+    }
+
     public PropertyTypeAssignment create(PropertyTypeAssignment assignment)
     {
         AssignSamplePropertyType assign = browseToAssignSamplePropertyType();
@@ -131,16 +164,31 @@ public class ApplicationRunner
         return getMenus().admin().types().sampleTypes();
     }
 
+    public ExperimentTypeBrowser browseToExperimentTypeBrowser()
+    {
+        return getMenus().admin().types().experimentTypes();
+    }
+
     public AddSampleTypeDialog browseToAddSampleTypeDialog()
     {
         return browseToSampleTypeBrowser().add();
     }
 
+    public AddExperimentTypeDialog browseToAddExperimentTypeDialog()
+    {
+        return browseToExperimentTypeBrowser().add();
+    }
+
     public SpaceBrowser browseToSpaceBrowser()
     {
         return getMenus().admin().spaces();
     }
 
+    public ProjectBrowser browseToProjectBrowser()
+    {
+        return getMenus().browse().projects();
+    }
+
     public AddSpaceDialog browseToAddSpaceDialog()
     {
         return browseToSpaceBrowser().addSpace();
@@ -191,6 +239,16 @@ public class ApplicationRunner
         return getMenus().newMenu().sample();
     }
 
+    public RegisterExperiment browseToRegisterExperiment()
+    {
+        return getMenus().newMenu().experiment();
+    }
+
+    public RegisterProject browseToRegisterProject()
+    {
+        return getMenus().newMenu().project();
+    }
+
     public void closeAllTabs()
     {
         getMenus().closeTabs();
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/PageProxy.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/PageProxy.java
index 38828e2ae46..4020e470cd9 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/PageProxy.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/PageProxy.java
@@ -125,7 +125,7 @@ public class PageProxy
                     // Force wait for the element.
                     // This makes sure that page object is returned only when all the
                     // expected elements are present.
-                    element.getText();
+                    element.getTagName();
                 }
             }
 
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/SeleniumTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/SeleniumTest.java
index 743b6d1376e..699b0be769e 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/SeleniumTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/SeleniumTest.java
@@ -42,6 +42,8 @@ import ch.systemsx.cisd.openbis.uitest.infra.matcher.SampleBrowserSampleTypeDrop
 import ch.systemsx.cisd.openbis.uitest.page.BrowserPage;
 import ch.systemsx.cisd.openbis.uitest.page.Cell;
 import ch.systemsx.cisd.openbis.uitest.page.Page;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ProjectBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeAssignmentBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterSample;
@@ -50,6 +52,9 @@ import ch.systemsx.cisd.openbis.uitest.page.tab.SampleTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SpaceBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.VocabularyBrowser;
 import ch.systemsx.cisd.openbis.uitest.type.Builder;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentBuilder;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentTypeBuilder;
+import ch.systemsx.cisd.openbis.uitest.type.ProjectBuilder;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyType;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyTypeAssignmentBuilder;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyTypeBuilder;
@@ -181,6 +186,11 @@ public abstract class SeleniumTest
         return openbis.browseToSampleTypeBrowser();
     }
 
+    protected ExperimentTypeBrowser experimentTypeBrowser()
+    {
+        return openbis.browseToExperimentTypeBrowser();
+    }
+
     protected VocabularyBrowser vocabularyBrowser()
     {
         return openbis.browseToVocabularyBrowser();
@@ -196,6 +206,11 @@ public abstract class SeleniumTest
         return openbis.browseToSpaceBrowser();
     }
 
+    protected ProjectBrowser projectBrowser()
+    {
+        return openbis.browseToProjectBrowser();
+    }
+
     protected RegisterSample sampleRegistrationPageFor(SampleType type)
     {
         return openbis.browseToRegisterSample().selectSampleType(type);
@@ -246,16 +261,31 @@ public abstract class SeleniumTest
         return new SpaceBuilder(openbis);
     }
 
+    protected ProjectBuilder aProject()
+    {
+        return new ProjectBuilder(openbis);
+    }
+
     protected SampleTypeBuilder aSampleType()
     {
         return new SampleTypeBuilder(openbis);
     }
 
+    protected ExperimentTypeBuilder anExperimentType()
+    {
+        return new ExperimentTypeBuilder(openbis);
+    }
+
     protected SampleBuilder aSample()
     {
         return new SampleBuilder(openbis);
     }
 
+    protected ExperimentBuilder anExperiment()
+    {
+        return new ExperimentBuilder(openbis);
+    }
+
     protected VocabularyBuilder aVocabulary()
     {
         return new VocabularyBuilder(openbis);
@@ -271,6 +301,16 @@ public abstract class SeleniumTest
         return new PropertyTypeBuilder(openbis, PropertyTypeDataType.INTEGER);
     }
 
+    protected PropertyTypeBuilder aRealPropertyType()
+    {
+        return new PropertyTypeBuilder(openbis, PropertyTypeDataType.REAL);
+    }
+
+    protected PropertyTypeBuilder aVarcharPropertyType()
+    {
+        return new PropertyTypeBuilder(openbis, PropertyTypeDataType.VARCHAR);
+    }
+
     protected PropertyTypeBuilder aVocabularyPropertyType(Vocabulary vocabulary)
     {
         return new PropertyTypeBuilder(openbis, vocabulary);
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContainsLinkMatcher.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContainsLinkMatcher.java
index f9afc3543c6..b552d162336 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContainsLinkMatcher.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContainsLinkMatcher.java
@@ -31,7 +31,7 @@ public class CellContainsLinkMatcher extends TypeSafeMatcher<Cell>
 
     public CellContainsLinkMatcher(String text, String url)
     {
-        expected = new Cell(text, url);
+        expected = new Cell(text, url, null);
     }
 
     @Override
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/BrowserPage.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/BrowserPage.java
index 8af404a7792..1350e81e7ff 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/BrowserPage.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/BrowserPage.java
@@ -18,8 +18,6 @@ package ch.systemsx.cisd.openbis.uitest.page;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -40,44 +38,30 @@ public abstract class BrowserPage extends NavigationPage
 
     protected abstract List<WebElement> getData();
 
-    protected List<WebElement> getVisible(List<WebElement> allElements)
-    {
-        List<WebElement> visibleElements = new ArrayList<WebElement>();
-        for (WebElement e : allElements)
-        {
-            if (e.isDisplayed())
-            {
-                visibleElements.add(e);
-            }
-        }
-        return visibleElements;
-    }
-
     public Collection<Map<String, Cell>> getTableContent()
     {
         List<Map<String, Cell>> content = new ArrayList<Map<String, Cell>>();
 
-        List<WebElement> columnNames = arrange(getVisible(getColumns()));
-        List<WebElement> gridValues = arrange(getVisible(getData()));
+        List<WebElement> columnNames = getColumns();
+        List<WebElement> gridValues = getData();
+
+        List<String> columns = new ArrayList<String>();
+        for (WebElement columnName : columnNames)
+        {
+            columns.add(columnName.getText());
+        }
 
         int index = 0;
         Map<String, Cell> map = new HashMap<String, Cell>();
+
         for (WebElement element : gridValues)
         {
-            String columnName = columnNames.get(index % columnNames.size()).getText();
-
-            List<WebElement> a = new ArrayList<WebElement>(this.findElements(element, ".//A"));
-            if (a.size() > 0)
-            {
-                map.put(columnName, new Cell(element.getText(), a.get(0).getAttribute("href")));
-            } else
-            {
-                map.put(columnName, new Cell(element.getText()));
-            }
+            String columnName = columns.get(index % columns.size());
+            map.put(columnName, new Cell(element.getText(), element.getAttribute("href"), element));
 
             index++;
 
-            if (index % columnNames.size() == 0)
+            if (index % columns.size() == 0)
             {
                 content.add(map);
                 map = new HashMap<String, Cell>();
@@ -98,26 +82,33 @@ public abstract class BrowserPage extends NavigationPage
         throw new IllegalStateException("Could not find " + browsable + " from " + toString());
     }
 
-    private List<WebElement> arrange(Collection<WebElement> elements)
+    protected abstract WebElement getDeleteButton();
+
+    public boolean deleteIfExists(String column, String value)
     {
-        List<WebElement> sorted = new ArrayList<WebElement>(elements);
-        Collections.sort(sorted, new Comparator<WebElement>()
+        for (Map<String, Cell> row : getTableContent())
+        {
+
+            Cell cell = row.get(column);
+            if (cell != null && cell.getText().equalsIgnoreCase(value))
             {
+                cell.getElement().click();
+                getDeleteButton().click();
 
-                @Override
-                public int compare(WebElement o1, WebElement o2)
+                for (WebElement ellu : this.findElements(cell.getElement(),
+                        "//*[@id='deletion-confirmation-dialog']//textarea"))
                 {
-                    int yDiff = o1.getLocation().getY() - o2.getLocation().getY();
-                    if (yDiff == 0)
-                    {
-                        return o1.getLocation().getX() - o2.getLocation().getX();
-                    } else
-                    {
-                        return yDiff;
-                    }
+                    ellu.sendKeys("reason for deletion");
                 }
-            });
-        return sorted;
+
+                this.findElement(cell.getElement(),
+                        "//*[@id='deletion-confirmation-dialog']//button[text()='OK' or text()='Yes']")
+                        .click();
+
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
@@ -125,14 +116,14 @@ public abstract class BrowserPage extends NavigationPage
     {
         String value = getClass().getSimpleName() + "\n";
         int numColumns = 0;
-        for (WebElement column : getVisible(getColumns()))
+        for (WebElement column : getColumns())
         {
             value += column.getText() + "\t";
             numColumns++;
         }
 
         int counter = 0;
-        for (WebElement cell : getVisible(getData()))
+        for (WebElement cell : getData())
         {
 
             if (counter % numColumns == 0)
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/Cell.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/Cell.java
index 067026d3b62..e22b84a1bb6 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/Cell.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/Cell.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.openbis.uitest.page;
 
+import org.openqa.selenium.WebElement;
+
 /**
  * @author anttil
  */
@@ -25,15 +27,13 @@ public class Cell
 
     private final String url;
 
-    public Cell(String text)
-    {
-        this(text, null);
-    }
+    private final WebElement element;
 
-    public Cell(String text, String url)
+    public Cell(String text, String url, WebElement element)
     {
         this.text = text;
         this.url = url;
+        this.element = element;
     }
 
     public String getText()
@@ -46,6 +46,11 @@ public class Cell
         return url;
     }
 
+    public WebElement getElement()
+    {
+        return this.element;
+    }
+
     public boolean hasLink()
     {
         return this.url != null;
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/dialog/AddExperimentTypeDialog.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/dialog/AddExperimentTypeDialog.java
new file mode 100644
index 00000000000..abb2da32c1c
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/dialog/AddExperimentTypeDialog.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.dialog;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import ch.systemsx.cisd.openbis.uitest.page.Page;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+
+public class AddExperimentTypeDialog extends Page
+{
+
+    @FindBy(id = "openbis_dialog-code-field-input")
+    private WebElement code;
+
+    @FindBy(id = "openbis_add-type-dialog-description-field-input")
+    private WebElement description;
+
+    @FindBy(id = "openbis_dialog-save-button")
+    private WebElement saveButton;
+
+    @FindBy(id = "openbis_dialog-cancel-button")
+    private WebElement cancelButton;
+
+    public ExperimentTypeBrowser save()
+    {
+        saveButton.click();
+        return get(ExperimentTypeBrowser.class);
+    }
+
+    public ExperimentTypeBrowser cancel()
+    {
+        cancelButton.click();
+        return get(ExperimentTypeBrowser.class);
+    }
+
+    public void fillWith(ExperimentType experimentType)
+    {
+        this.code.sendKeys(experimentType.getCode());
+        this.description.sendKeys(experimentType.getDescription());
+    }
+
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/fragment/VarcharInput.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/fragment/VarcharInput.java
new file mode 100644
index 00000000000..a9cafc3d8eb
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/fragment/VarcharInput.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.fragment;
+
+import org.openqa.selenium.WebElement;
+
+import ch.systemsx.cisd.openbis.uitest.page.Fragment;
+
+/**
+ * @author anttil
+ */
+public class VarcharInput extends Fragment
+{
+    @Override
+    public void fillWith(Object value)
+    {
+        WebElement x = this.findElement(element, "input");
+        x.clear();
+        x.sendKeys(value.toString());
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/AdminMenu.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/AdminMenu.java
index f2b192df3fd..8142ede00d8 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/AdminMenu.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/AdminMenu.java
@@ -23,6 +23,7 @@ import org.openqa.selenium.support.FindBy;
 import ch.systemsx.cisd.openbis.uitest.infra.NotAlwaysPresent;
 import ch.systemsx.cisd.openbis.uitest.infra.SeleniumTest;
 import ch.systemsx.cisd.openbis.uitest.page.Page;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SampleTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SpaceBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.VocabularyBrowser;
@@ -46,6 +47,10 @@ public class AdminMenu extends Page
     @FindBy(id = "openbis_top-menu_SAMPLE_MENU_TYPES")
     private WebElement sampleTypes;
 
+    @NotAlwaysPresent
+    @FindBy(id = "openbis_top-menu_EXPERIMENT_MENU_TYPES")
+    private WebElement experimentTypes;
+
     @FindBy(id = "ADMINISTRATION_MENU_MANAGE_AUTHORIZATION")
     private WebElement authorization;
 
@@ -81,6 +86,12 @@ public class AdminMenu extends Page
         return get(SampleTypeBrowser.class);
     }
 
+    public ExperimentTypeBrowser experimentTypes()
+    {
+        experimentTypes.click();
+        return get(ExperimentTypeBrowser.class);
+    }
+
     public AuthorizationMenu authorization()
     {
         Actions builder = new Actions(SeleniumTest.driver);
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/BrowseMenu.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/BrowseMenu.java
index c788c409cde..adbd1af9d04 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/BrowseMenu.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/BrowseMenu.java
@@ -20,6 +20,7 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 import ch.systemsx.cisd.openbis.uitest.page.Page;
+import ch.systemsx.cisd.openbis.uitest.page.tab.ProjectBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SampleBrowser;
 
 public class BrowseMenu extends Page
@@ -28,9 +29,19 @@ public class BrowseMenu extends Page
     @FindBy(id = "openbis_top-menu_SAMPLE_MENU_BROWSE")
     private WebElement samples;
 
+    @FindBy(id = "openbis_top-menu_PROJECT_MENU_BROWSE")
+    private WebElement projects;
+
     public SampleBrowser samples()
     {
         samples.click();
         return get(SampleBrowser.class);
     }
+
+    public ProjectBrowser projects()
+    {
+        projects.click();
+        return get(ProjectBrowser.class);
+    }
+
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/NewMenu.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/NewMenu.java
index bcf8993f36f..5b6169ea763 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/NewMenu.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/menu/NewMenu.java
@@ -20,6 +20,8 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 import ch.systemsx.cisd.openbis.uitest.page.Page;
+import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterExperiment;
+import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterProject;
 import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterSample;
 
 public class NewMenu extends Page
@@ -28,9 +30,27 @@ public class NewMenu extends Page
     @FindBy(id = "openbis_top-menu_SAMPLE_MENU_NEW")
     private WebElement sample;
 
+    @FindBy(id = "openbis_top-menu_PROJECT_MENU_NEW")
+    private WebElement project;
+
+    @FindBy(id = "openbis_top-menu_EXPERIMENT_MENU_NEW")
+    private WebElement experiment;
+
     public RegisterSample sample()
     {
         sample.click();
         return get(RegisterSample.class);
     }
+
+    public RegisterProject project()
+    {
+        project.click();
+        return get(RegisterProject.class);
+    }
+
+    public RegisterExperiment experiment()
+    {
+        experiment.click();
+        return get(RegisterExperiment.class);
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
new file mode 100644
index 00000000000..c03cb25f248
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.tab;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+
+import ch.systemsx.cisd.openbis.uitest.page.BrowserPage;
+import ch.systemsx.cisd.openbis.uitest.page.dialog.AddExperimentTypeDialog;
+
+public class ExperimentTypeBrowser extends BrowserPage
+{
+
+    @FindBy(id = "add-entity-type-ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentTypeGrid")
+    private WebElement addButton;
+
+    @FindBy(id = "edit-entity-type")
+    private WebElement editButton;
+
+    @FindBy(id = "delete-entity-type")
+    private WebElement deleteButton;
+
+    @FindBys(
+        {
+                @FindBy(id = "openbis_experiment-type-browser-grid"),
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
+    private List<WebElement> columns;
+
+    @FindBys(
+        {
+                @FindBy(id = "openbis_experiment-type-browser-grid"),
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
+    private List<WebElement> data;
+
+    public AddExperimentTypeDialog add()
+    {
+        addButton.click();
+        return get(AddExperimentTypeDialog.class);
+    }
+
+    @Override
+    protected List<WebElement> getColumns()
+    {
+        return this.columns;
+    }
+
+    @Override
+    protected List<WebElement> getData()
+    {
+        return this.data;
+    }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.deleteButton;
+    }
+}
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
new file mode 100644
index 00000000000..21c4c919dcf
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.tab;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+
+import ch.systemsx.cisd.openbis.uitest.page.BrowserPage;
+
+public class ProjectBrowser extends BrowserPage
+{
+
+    @FindBys(
+        {
+                @FindBy(id = "openbis_project-browser-grid"),
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
+    private List<WebElement> columns;
+
+    @FindBys(
+        {
+                @FindBy(id = "openbis_project-browser-grid"),
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
+    private List<WebElement> data;
+
+    @FindBy(id = "openbis_project-browser-delete")
+    private WebElement deleteButton;
+
+    @Override
+    protected List<WebElement> getColumns()
+    {
+        return this.columns;
+    }
+
+    @Override
+    protected List<WebElement> getData()
+    {
+        return this.data;
+    }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return deleteButton;
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
index 8e22fe0afa8..ac5489469c4 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
@@ -30,18 +30,21 @@ public class PropertyTypeAssignmentBrowser extends BrowserPage
     @FindBys(
         {
                 @FindBy(id = "openbis_property-type-assignment-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]//span") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_property-type-assignment-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]/div") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     @FindBy(id = "openbis_property-type-assignment-browser-grid-edit")
     private WebElement editPropertyTypeButton;
 
+    @FindBy(id = "openbis_property-type-assignment-browser-grid-release")
+    private WebElement releasePropertyTypeButton;
+
     @Override
     protected List<WebElement> getColumns()
     {
@@ -53,4 +56,10 @@ public class PropertyTypeAssignmentBrowser extends BrowserPage
     {
         return this.data;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.releasePropertyTypeButton;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
index 97148459d69..bd3f7333729 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
@@ -30,18 +30,21 @@ public class PropertyTypeBrowser extends BrowserPage
     @FindBys(
         {
                 @FindBy(id = "openbis_property-type-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]//span") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_property-type-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]/div") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     @FindBy(id = "openbis_property-type-browser-grid-add-button")
     private WebElement addPropertyTypeButton;
 
+    @FindBy(id = "openbis_property-type-browser-grid-delete-button")
+    private WebElement deletePropertyTypeButton;
+
     @Override
     protected List<WebElement> getColumns()
     {
@@ -53,4 +56,10 @@ public class PropertyTypeBrowser extends BrowserPage
     {
         return this.data;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.deletePropertyTypeButton;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterExperiment.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterExperiment.java
new file mode 100644
index 00000000000..dc6ac46e4ce
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterExperiment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.tab;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+
+import ch.systemsx.cisd.openbis.uitest.infra.NotAlwaysPresent;
+import ch.systemsx.cisd.openbis.uitest.page.NavigationPage;
+import ch.systemsx.cisd.openbis.uitest.type.Experiment;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+import ch.systemsx.cisd.openbis.uitest.type.Sample;
+
+public class RegisterExperiment extends NavigationPage
+{
+
+    @FindBys(
+        {
+                @FindBy(id = "openbis_select_experiment-typeopenbis_experiment-registration"),
+                @FindBy(xpath = "img") })
+    private WebElement experimentTypeList;
+
+    @FindBy(className = "x-combo-list-item")
+    private List<WebElement> experimentTypeChoices;
+
+    @NotAlwaysPresent
+    @FindBy(id = "openbis_generic-experiment-register_formcode-input")
+    private WebElement code;
+
+    @NotAlwaysPresent
+    @FindBys(
+        {
+                @FindBy(id = "openbis_select_projectgeneric-experiment-register_form"),
+                @FindBy(xpath = "img") })
+    private WebElement projectList;
+
+    @FindBy(className = "x-combo-list-item")
+    private List<WebElement> projectChoices;
+
+    @NotAlwaysPresent
+    @FindBy(id = "generic-experiment-register_form_samples-input")
+    private WebElement samples;
+
+    @NotAlwaysPresent
+    @FindBy(id = "openbis_generic-experiment-register_formsave-button")
+    private WebElement saveButton;
+
+    public void fillWith(Experiment experiment)
+    {
+        code.sendKeys(experiment.getCode());
+        projectList.click();
+        select(projectChoices, experiment.getProject().getCode() + " ("
+                + experiment.getProject().getSpace().getCode() + ")");
+
+        samples.clear();
+        for (Sample sample : experiment.getSamples())
+        {
+            samples.sendKeys(sample.getCode() + ", ");
+        }
+    }
+
+    public RegisterExperiment selectExperimentType(ExperimentType experimentType)
+    {
+        experimentTypeList.click();
+        select(experimentTypeChoices, experimentType.getCode());
+        return get(RegisterExperiment.class);
+    }
+
+    public RegisterExperiment save()
+    {
+        this.saveButton.click();
+        return get(RegisterExperiment.class);
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Register Experiment tab";
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterProject.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterProject.java
new file mode 100644
index 00000000000..d0f9ae8c0b7
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterProject.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.page.tab;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.FindBys;
+
+import ch.systemsx.cisd.openbis.uitest.infra.NotAlwaysPresent;
+import ch.systemsx.cisd.openbis.uitest.page.NavigationPage;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
+
+public class RegisterProject extends NavigationPage
+{
+
+    @FindBy(id = "openbis_project-register_form_code-input")
+    private WebElement code;
+
+    @NotAlwaysPresent
+    @FindBys(
+        {
+                @FindBy(id = "openbis_select_group-selectopenbis_project-register_form"),
+                @FindBy(xpath = "img") })
+    private WebElement spaceList;
+
+    @FindBy(className = "x-combo-list-item")
+    private List<WebElement> spaceChoices;
+
+    @FindBy(id = "openbis_project-register_formsave-button")
+    private WebElement saveButton;
+
+    public void fillWith(Project project)
+    {
+        code.sendKeys(project.getCode());
+        spaceList.click();
+        select(spaceChoices, project.getSpace().getCode());
+    }
+
+    public RegisterProject save()
+    {
+        this.saveButton.click();
+        return get(RegisterProject.class);
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Register Sample tab";
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterSample.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterSample.java
index 4412066153b..54139db1dab 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterSample.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RegisterSample.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.uitest.infra.NotAlwaysPresent;
 import ch.systemsx.cisd.openbis.uitest.page.Fragment;
 import ch.systemsx.cisd.openbis.uitest.page.NavigationPage;
 import ch.systemsx.cisd.openbis.uitest.page.fragment.TermSelector;
+import ch.systemsx.cisd.openbis.uitest.page.fragment.VarcharInput;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyType;
 import ch.systemsx.cisd.openbis.uitest.type.PropertyTypeDataType;
 import ch.systemsx.cisd.openbis.uitest.type.Sample;
@@ -102,6 +103,9 @@ public class RegisterSample extends NavigationPage
         if (type.equals(PropertyTypeDataType.CONTROLLED_VOCABULARY))
         {
             fragment = get(TermSelector.class);
+        } else if (type.equals(PropertyTypeDataType.VARCHAR))
+        {
+            fragment = get(VarcharInput.class);
         } else
         {
             throw new IllegalArgumentException("unknown type " + type);
@@ -114,7 +118,7 @@ public class RegisterSample extends NavigationPage
     private WebElement getPropertyElement(PropertyType type)
     {
         return this.findElement(this.mainForm, "//div[@id='openbis_generic-sample-register_form"
-                + type.getCode() + "']");
+                + type.getCode().toLowerCase().replace(".", "-DOT-") + "']");
     }
 
     public RegisterSample selectSampleType(SampleType sampleType)
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
index e4fd8b39ff7..8f2aa5e2397 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
@@ -56,4 +56,11 @@ public class RoleAssignmentBrowser extends BrowserPage
     {
         return this.data;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
index 9afef8da26f..cb0aecb379e 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
@@ -23,6 +23,7 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.FindBys;
 
+import ch.systemsx.cisd.openbis.uitest.infra.NotAlwaysPresent;
 import ch.systemsx.cisd.openbis.uitest.page.BrowserPage;
 import ch.systemsx.cisd.openbis.uitest.type.SampleType;
 
@@ -32,13 +33,13 @@ public class SampleBrowser extends BrowserPage
     @FindBys(
         {
                 @FindBy(id = "openbis_sample-browser_main-grid"),
-                @FindBy(xpath = ".//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_sample-browser_main-grid"),
-                @FindBy(xpath = ".//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     @FindBy(id = "openbis_sample-browser_main_add-button")
@@ -50,6 +51,7 @@ public class SampleBrowser extends BrowserPage
                 @FindBy(xpath = "img") })
     private WebElement sampleTypeList;
 
+    @NotAlwaysPresent
     @FindBy(className = "x-combo-list-item")
     private List<WebElement> sampleTypeChoices;
 
@@ -59,6 +61,7 @@ public class SampleBrowser extends BrowserPage
                 @FindBy(xpath = "img") })
     private WebElement spaceList;
 
+    @NotAlwaysPresent
     @FindBy(className = "x-combo-list-item")
     private List<WebElement> spaceChoices;
 
@@ -108,4 +111,11 @@ public class SampleBrowser extends BrowserPage
 
         return sampleTypes;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
index 75e02e0bd54..87f5ab96dc2 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
@@ -29,23 +29,25 @@ import ch.systemsx.cisd.openbis.uitest.type.SampleType;
 
 public class SampleTypeBrowser extends BrowserPage
 {
-
-    @FindBy(id = "add-entity-type")
+    @FindBy(id = "add-entity-type-ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleTypeGrid")
     private WebElement addSampleTypeButton;
 
     @FindBy(id = "edit-entity-type")
     private WebElement editSampleTypeButton;
 
+    @FindBy(id = "delete-entity-type")
+    private WebElement deleteSampleTypeButton;
+
     @FindBys(
         {
                 @FindBy(id = "openbis_sample-type-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_sample-type-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     public AddSampleTypeDialog add()
@@ -79,4 +81,10 @@ public class SampleTypeBrowser extends BrowserPage
         }
         throw new IllegalArgumentException("Sample type browser does not contain " + type);
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.deleteSampleTypeButton;
+    }
 }
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
index f6d41ea7a66..b547c7ec39f 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
@@ -31,18 +31,21 @@ public class SpaceBrowser extends BrowserPage
     @FindBys(
         {
                 @FindBy(id = "openbis_space-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]//span") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_space-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]/div") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     @FindBy(id = "openbis_space-browser_add-button")
     private WebElement addSpaceButton;
 
+    @FindBy(id = "openbis_space-browser_delete-button")
+    private WebElement deleteButton;
+
     public AddSpaceDialog addSpace()
     {
         addSpaceButton.click();
@@ -60,4 +63,10 @@ public class SpaceBrowser extends BrowserPage
     {
         return this.data;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.deleteButton;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
index 55d202eb48b..058e047dae5 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
@@ -31,18 +31,21 @@ public class VocabularyBrowser extends BrowserPage
     @FindBys(
         {
                 @FindBy(id = "openbis_vocabulary-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-header \")]//span") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-header ')]//span[not(*)]") })
     private List<WebElement> columns;
 
     @FindBys(
         {
                 @FindBy(id = "openbis_vocabulary-browser-grid"),
-                @FindBy(xpath = "//*[contains(@class, \"x-grid\") and contains(@class, \"-col \")]/div") })
+                @FindBy(xpath = ".//td[not(ancestor::div[contains(@style,'display:none')]) and contains(@class, 'x-grid') and contains(@class, '-col ')]//*[not(*)]") })
     private List<WebElement> data;
 
     @FindBy(id = "openbis_vocabulary-browser_add-button")
     private WebElement addVocabularyButton;
 
+    @FindBy(id = "openbis_vocabulary-browser_delete-button")
+    private WebElement deleteVocabularyButton;
+
     public AddVocabularyDialog add()
     {
         addVocabularyButton.click();
@@ -60,4 +63,10 @@ public class VocabularyBrowser extends BrowserPage
     {
         return this.data;
     }
+
+    @Override
+    protected WebElement getDeleteButton()
+    {
+        return this.deleteVocabularyButton;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
index 2c210ccbc0b..9efe42f9a73 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Collection;
 import java.util.Map;
 
 import ch.systemsx.cisd.openbis.uitest.infra.Browsable;
@@ -33,11 +34,14 @@ public class Experiment implements EntityType, Browsable
 
     private Project project;
 
-    Experiment(ExperimentType type, String code, Project project)
+    private Collection<Sample> samples;
+
+    Experiment(ExperimentType type, String code, Project project, Collection<Sample> samples)
     {
         this.type = type;
         this.code = code;
         this.project = project;
+        this.samples = samples;
     }
 
     @Override
@@ -63,6 +67,11 @@ public class Experiment implements EntityType, Browsable
         return project;
     }
 
+    public Collection<Sample> getSamples()
+    {
+        return samples;
+    }
+
     void setType(ExperimentType type)
     {
         this.type = type;
@@ -72,4 +81,9 @@ public class Experiment implements EntityType, Browsable
     {
         this.project = project;
     }
+
+    void setSamples(Collection<Sample> samples)
+    {
+        this.samples = samples;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentBuilder.java
new file mode 100644
index 00000000000..6d156edf0c2
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentBuilder.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.UUID;
+
+import ch.systemsx.cisd.openbis.uitest.infra.ApplicationRunner;
+
+/**
+ * @author anttil
+ */
+public class ExperimentBuilder implements Builder<Experiment>
+{
+
+    private ApplicationRunner openbis;
+
+    private ExperimentType type;
+
+    private String code;
+
+    private Project project;
+
+    private Collection<Sample> samples;
+
+    public ExperimentBuilder(ApplicationRunner openbis)
+    {
+        this.openbis = openbis;
+        this.type = null;
+        this.code = UUID.randomUUID().toString();
+        this.project = null;
+        this.samples = new ArrayList<Sample>();
+    }
+
+    public ExperimentBuilder ofType(ExperimentType type)
+    {
+        this.type = type;
+        return this;
+    }
+
+    public ExperimentBuilder in(Project project)
+    {
+        this.project = project;
+        return this;
+    }
+
+    public ExperimentBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
+    public ExperimentBuilder withSamples(Sample... samples)
+    {
+        this.samples = new HashSet<Sample>();
+        for (Sample sample : samples)
+        {
+            this.samples.add(sample);
+        }
+        return this;
+    }
+
+    @Override
+    public Experiment build()
+    {
+        if (type == null)
+        {
+            type = new ExperimentTypeBuilder(openbis).build();
+        }
+        if (project == null)
+        {
+            project = new ProjectBuilder(openbis).build();
+        }
+
+        return openbis.create(new Experiment(type, code, project, samples));
+    }
+
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
index 6b1525a2555..5d4526a1825 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
@@ -16,12 +16,45 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.uitest.infra.Browsable;
+import ch.systemsx.cisd.openbis.uitest.page.Cell;
+
 /**
- * 
- *
  * @author anttil
  */
-public class ExperimentType
+public class ExperimentType implements Browsable
 {
+    private final String code;
+
+    private String description;
+
+    public ExperimentType(String code, String description)
+    {
+        this.code = code;
+        this.description = description;
+    }
+
+    @Override
+    public boolean isRepresentedBy(Map<String, Cell> row)
+    {
+        Cell codeCell = row.get("Code");
+        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getDescription()
+    {
+        return description;
+    }
 
+    void setDescription(String description)
+    {
+        this.description = description;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentTypeBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentTypeBuilder.java
new file mode 100644
index 00000000000..8c3e45c047b
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentTypeBuilder.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.type;
+
+import java.util.UUID;
+
+import ch.systemsx.cisd.openbis.uitest.infra.ApplicationRunner;
+
+/**
+ * @author anttil
+ */
+public class ExperimentTypeBuilder implements Builder<ExperimentType>
+{
+
+    private ApplicationRunner openbis;
+
+    private String code;
+
+    private String description;
+
+    public ExperimentTypeBuilder(ApplicationRunner openbis)
+    {
+        this.openbis = openbis;
+        this.code = UUID.randomUUID().toString();
+        this.description = "";
+    }
+
+    public ExperimentTypeBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
+    @Override
+    public ExperimentType build()
+    {
+        return openbis.create(new ExperimentType(code, description));
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
index 53d6be94459..c6b193340fe 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
@@ -32,7 +32,7 @@ public class Project implements Browsable
 
     private String description;
 
-    Project(String code, Space space, String description)
+    Project(String code, String description, Space space)
     {
         this.code = code;
         this.space = space;
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ProjectBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ProjectBuilder.java
new file mode 100644
index 00000000000..b3015a22cf1
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ProjectBuilder.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.uitest.type;
+
+import java.util.UUID;
+
+import ch.systemsx.cisd.openbis.uitest.infra.ApplicationRunner;
+
+/**
+ * @author anttil
+ */
+public class ProjectBuilder implements Builder<Project>
+{
+
+    private ApplicationRunner openbis;
+
+    private String code;
+
+    private String description;
+
+    private Space space;
+
+    public ProjectBuilder(ApplicationRunner openbis)
+    {
+        this.openbis = openbis;
+        this.code = UUID.randomUUID().toString();
+        this.description = "";
+        this.space = null;
+    }
+
+    public ProjectBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
+    public ProjectBuilder in(Space space)
+    {
+        this.space = space;
+        return this;
+    }
+
+    @Override
+    public Project build()
+    {
+        if (space == null)
+        {
+            space = new SpaceBuilder(openbis).build();
+        }
+        return openbis.create(new Project(code, description, space));
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeBuilder.java
index 80a1035fa11..7a92a71946a 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeBuilder.java
@@ -54,6 +54,18 @@ public class PropertyTypeBuilder implements Builder<PropertyType>
         this.vocabulary = vocabulary;
     }
 
+    public PropertyTypeBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
+    public PropertyTypeBuilder withDescription(String description)
+    {
+        this.description = description;
+        return this;
+    }
+
     public PropertyTypeBuilder withLabel(String label)
     {
         this.label = label;
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
index 45540d80c5b..83d15cff2aa 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
@@ -58,6 +58,18 @@ public class SampleBuilder implements Builder<Sample>
         return this;
     }
 
+    public SampleBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
+    public SampleBuilder in(Space space)
+    {
+        this.space = space;
+        return this;
+    }
+
     public SampleBuilder withProperty(PropertyType propertyType, Object value)
     {
         this.properties.put(propertyType, value);
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleTypeBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleTypeBuilder.java
index cdc37fd1c3a..822ce2f23f5 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleTypeBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleTypeBuilder.java
@@ -83,6 +83,18 @@ public class SampleTypeBuilder implements Builder<SampleType>
         return this;
     }
 
+    public SampleTypeBuilder thatShowsParents()
+    {
+        this.showsParents = true;
+        return this;
+    }
+
+    public SampleTypeBuilder thatShowsContainer()
+    {
+        this.showsContainer = true;
+        return this;
+    }
+
     @Override
     public SampleType build()
     {
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SpaceBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SpaceBuilder.java
index a499be83d44..c0fc31db18f 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SpaceBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SpaceBuilder.java
@@ -28,9 +28,9 @@ public class SpaceBuilder implements Builder<Space>
 
     private ApplicationRunner openbis;
 
-    private final String code;
+    private String code;
 
-    private final String description;
+    private String description;
 
     public SpaceBuilder(ApplicationRunner openbis)
     {
@@ -39,6 +39,12 @@ public class SpaceBuilder implements Builder<Space>
         this.description = "";
     }
 
+    public SpaceBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
     @Override
     public Space build()
     {
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/VocabularyBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/VocabularyBuilder.java
index f9548ff2091..69e0c4679bf 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/VocabularyBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/VocabularyBuilder.java
@@ -54,6 +54,12 @@ public class VocabularyBuilder implements Builder<Vocabulary>
         return this;
     }
 
+    public VocabularyBuilder withCode(String code)
+    {
+        this.code = code;
+        return this;
+    }
+
     public VocabularyBuilder withTerms(String... content)
     {
         this.terms = new HashSet<String>();
-- 
GitLab