diff --git a/testing/schrodingertest/src/test/java/com/evolveum/midpoint/testing/schrodinger/UsersTest.java b/testing/schrodingertest/src/test/java/com/evolveum/midpoint/testing/schrodinger/UsersTest.java
index be97aa19a03..f164294eb5a 100644
--- a/testing/schrodingertest/src/test/java/com/evolveum/midpoint/testing/schrodinger/UsersTest.java
+++ b/testing/schrodingertest/src/test/java/com/evolveum/midpoint/testing/schrodinger/UsersTest.java
@@ -9,12 +9,23 @@
import com.codeborne.selenide.Selenide;
+import com.evolveum.midpoint.schrodinger.component.assignmentholder.AssignmentHolderObjectListTable;
import com.evolveum.midpoint.schrodinger.component.common.Paging;
+import com.evolveum.midpoint.schrodinger.component.common.Popover;
+import com.evolveum.midpoint.schrodinger.component.common.Search;
import com.evolveum.midpoint.schrodinger.page.user.ListUsersPage;
import com.evolveum.midpoint.schrodinger.page.user.UserPage;
+import com.evolveum.midpoint.testing.schrodinger.scenarios.ScenariosCommons;
+
+import org.openqa.selenium.Keys;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import java.io.File;
+import java.io.IOException;
+
import static com.codeborne.selenide.Selenide.screenshot;
/**
@@ -22,6 +33,20 @@
*/
public class UsersTest extends AbstractSchrodingerTest {
+ private static final File LOOKUP_TABLE_SUBTYPES = new File("src/test/resources/configuration/objects/lookuptable/subtypes.xml");
+ private static final File OT_FOR_LOOKUP_TABLE_SUBTYPES = new File("src/test/resources/configuration/objects/objecttemplate/object-template-for-lookup-table-subtypes.xml");
+ private static final File SYSTEM_CONFIG_WITH_LOOKUP_TABLE = new File("src/test/resources/configuration/objects/systemconfig/system-configuration-with-lookup-table.xml");
+
+ @BeforeClass
+ @Override
+ public void beforeClass() throws IOException {
+ super.beforeClass();
+ importObject(LOOKUP_TABLE_SUBTYPES, true);
+ importObject(OT_FOR_LOOKUP_TABLE_SUBTYPES, true);
+ importObject(SYSTEM_CONFIG_WITH_LOOKUP_TABLE, true);
+
+ }
+
@Test
public void testUserTablePaging() {
ListUsersPage users = basicPage.listUsers();
@@ -52,6 +77,45 @@ public void testUserTablePaging() {
paging.actualPageMinusOne();
}
+ @Test
+ public void testSearchWithLookupTable() {
+
+ UserPage user = basicPage.newUser();
+ user.selectTabBasic()
+ .form()
+ .addAttributeValue("name", "searchUser")
+ .addAttributeValue("subtype", "Extern")
+ .and()
+ .and()
+ .clickSave();
+
+
+ ListUsersPage users = basicPage.listUsers();
+
+ Assert.assertTrue(
+ users
+ .table()
+ .search()
+ .byItem("subtype")
+ .inputValueWithEnter("Extern")
+ .and()
+ .and()
+ .currentTableContains("searchUser")
+ );
+
+ Assert.assertFalse(
+ users
+ .table()
+ .search()
+ .byItem("subtype")
+ .inputValueWithEnter("Employee")
+ .and()
+ .and()
+ .currentTableContains("searchUser")
+ );
+
+ }
+
private void addUser(String name) {
UserPage user = basicPage.newUser();
user.selectTabBasic()
diff --git a/testing/schrodingertest/src/test/resources/configuration/objects/lookuptable/subtypes.xml b/testing/schrodingertest/src/test/resources/configuration/objects/lookuptable/subtypes.xml
new file mode 100644
index 00000000000..414ca8ecae8
--- /dev/null
+++ b/testing/schrodingertest/src/test/resources/configuration/objects/lookuptable/subtypes.xml
@@ -0,0 +1,18 @@
+
+
+
+ Subtypes
+
+ EMP
+
+
+
+ EXT
+
+
+
diff --git a/testing/schrodingertest/src/test/resources/configuration/objects/objecttemplate/object-template-for-lookup-table-subtypes.xml b/testing/schrodingertest/src/test/resources/configuration/objects/objecttemplate/object-template-for-lookup-table-subtypes.xml
new file mode 100644
index 00000000000..5e8e5940de1
--- /dev/null
+++ b/testing/schrodingertest/src/test/resources/configuration/objects/objecttemplate/object-template-for-lookup-table-subtypes.xml
@@ -0,0 +1,15 @@
+
+
+
+ lookup table item subtypes
+ -
+
[subtype]
+ subtype
+
+
+
diff --git a/testing/schrodingertest/src/test/resources/configuration/objects/systemconfig/system-configuration-with-lookup-table.xml b/testing/schrodingertest/src/test/resources/configuration/objects/systemconfig/system-configuration-with-lookup-table.xml
new file mode 100644
index 00000000000..76a458a37ef
--- /dev/null
+++ b/testing/schrodingertest/src/test/resources/configuration/objects/systemconfig/system-configuration-with-lookup-table.xml
@@ -0,0 +1,366 @@
+
+
+
+ SystemConfiguration
+
+
+
+
+
+ ERROR
+ ro.isdc.wro.extensions.processor.css.Less4jProcessor
+
+
+ OFF
+ org.hibernate.engine.jdbc.spi.SqlExceptionHelper
+
+
+ OFF
+ org.hibernate.engine.jdbc.batch.internal.BatchingBatch
+
+
+ WARN
+ org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl
+
+
+ OFF
+ org.hibernate.internal.ExceptionMapperStandardImpl
+
+
+ OFF
+ net.sf.jasperreports.engine.fill.JRFillDataset
+
+
+ WARN
+ org.apache.wicket.resource.PropertiesFactory
+
+
+ ERROR
+ org.springframework.context.support.ResourceBundleMessageSource
+
+
+ INFO
+ com.evolveum.midpoint.model.impl.lens.projector.Projector
+
+
+ INFO
+ com.evolveum.midpoint.model.impl.lens.Clockwork
+
+
+ %date [%X{subsystem}] [%thread] %level \(%logger\): %msg%n
+ MIDPOINT_LOG
+ ${midpoint.home}/log/midpoint.log
+ ${midpoint.home}/log/midpoint-%d{yyyy-MM-dd}.%i.log
+ 10
+ 100MB
+ true
+
+
+ %date %level: %msg%n
+ MIDPOINT_PROFILE_LOG
+ ${midpoint.home}/log/midpoint-profile.log
+ ${midpoint.home}/log/midpoint-profile-%d{yyyy-MM-dd}.%i.log
+ 10
+ 100MB
+ true
+
+ MIDPOINT_LOG
+ INFO
+
+ false
+ false
+
+
+
+
+ P3M
+
+
+ P1M
+
+
+
+
+
+ performance
+ Performance tracing
+ true
+ true
+ performance-trace %{timestamp} %{focusName} %{milliseconds}
+ true
+ true
+
+
+ functional
+ Functional tracing
+ true
+ functional-trace %{timestamp} %{focusName}
+ true
+ true
+ true
+
+ normal
+
+
+
+ functional-model-logging
+ Functional tracing (with model logging)
+ true
+ functional-trace %{timestamp} %{focusName}
+ true
+ true
+ true
+
+
+ com.evolveum.midpoint.model
+ TRACE
+
+
+
+ normal
+
+
+
+ functional-sql-logging
+ Functional tracing (with SQL logging)
+ true
+ functional-trace %{timestamp} %{focusName}
+ true
+ true
+ true
+
+
+ org.hibernate.SQL
+ TRACE
+
+
+
+ normal
+
+
+
+
+
+
+ /self/profile
+
+ View/edit your profile
+
+ fa fa-user
+
+ green
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfProfile
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll
+
+
+ /self/credentials
+
+ View/edit your credentials
+
+ fa fa-shield
+
+ blue
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfCredentials
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll
+
+
+ /admin/users
+
+
+ fa fa-users
+
+ red
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#users
+
+
+ /admin/resources
+
+
+ fa fa-database
+
+ purple
+ http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#resources
+
+
+
+
+ safe
+
+ "Safe" expression profile. It is supposed to contain only operations that are "safe",
+ i.e. operations that have very little risk to harm the system, circumvent midPoint security
+ and so on. Use of those operations should be reasonably safe in all expressions.
+ However, there are limitations. This profile may incomplete or it may even be not completely secure.
+ Proper security testing of this profile was not yet conducted. It is provided here "AS IS",
+ without any guarantees. Use at your own risk.
+
+ deny
+
+ asIs
+ allow
+
+
+ path
+ allow
+
+
+ value
+ allow
+
+
+ const
+ allow
+
+
+ script
+ deny
+
+
+
+
+ script-safe
+ deny
+
+ com.evolveum.midpoint.xml.ns._public.common.common_3
+ MidPoint common schema - generated bean classes
+ allow
+
+
+ com.evolveum.prism.xml.ns._public.types_3
+ Prism schema - bean classes
+ allow
+
+
+ java.lang.Integer
+ allow
+
+
+ java.lang.Object
+ Basic Java operations.
+ deny
+
+ equals
+ allow
+
+
+ hashCode
+ allow
+
+
+
+ java.lang.String
+ String operations are generally safe. But Groovy is adding execute() method which is very dangerous.
+ allow
+
+ execute
+ deny
+
+
+
+ java.lang.CharSequence
+ allow
+
+
+ java.lang.Enum
+ allow
+
+
+ java.util.List
+ List operations are generally safe. But Groovy is adding execute() method which is very dangerous.
+ allow
+
+ execute
+ deny
+
+
+
+ java.util.ArrayList
+ List operations are generally safe. But Groovy is adding execute() method which is very dangerous.
+ allow
+
+ execute
+ deny
+
+
+
+ java.util.Map
+ allow
+
+
+ java.util.HashMap
+ allow
+
+
+ java.util.Date
+ allow
+
+
+ javax.xml.namespace.QName
+ allow
+
+
+ javax.xml.datatype.XMLGregorianCalendar
+ allow
+
+
+ java.lang.System
+ Just a few methods of System are safe enough.
+ deny
+
+ currentTimeMillis
+ allow
+
+
+
+ java.lang.IllegalStateException
+ Basic Java exception. Also used in test.
+ allow
+
+
+ java.lang.IllegalArgumentException
+ Basic Java exception.
+ allow
+
+
+ com.evolveum.midpoint.model.common.expression.functions.BasicExpressionFunctions
+ MidPoint basic functions library
+ allow
+
+
+ com.evolveum.midpoint.model.common.expression.functions.LogExpressionFunctions
+ MidPoint logging functions library
+ allow
+
+
+ com.evolveum.midpoint.report.impl.ReportFunctions
+ MidPoint report functions library
+ allow
+
+
+ org.apache.commons.lang.StringUtils
+ Apache Commons: Strings
+ allow
+
+
+
+
+
+ c:UserType
+
+
diff --git a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/Component.java b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/Component.java
index c37c00700dc..15b0a994596 100644
--- a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/Component.java
+++ b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/Component.java
@@ -6,8 +6,11 @@
*/
package com.evolveum.midpoint.schrodinger.component;
+import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement;
+import com.evolveum.midpoint.schrodinger.util.Schrodinger;
+
/**
* Created by Viliam Repan (lazyman).
*/
@@ -37,4 +40,13 @@ public T getParent() {
public SelenideElement getParentElement() {
return parentElement;
}
+
+ protected SelenideElement getDisplayedElement(ElementsCollection elements) {
+ for (SelenideElement element : elements) {
+ if (element.isDisplayed()) {
+ return element;
+ }
+ }
+ return null;
+ }
}
diff --git a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Popover.java b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Popover.java
index 3cf15ff3323..71698c2bf9a 100644
--- a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Popover.java
+++ b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Popover.java
@@ -12,6 +12,8 @@
import com.evolveum.midpoint.schrodinger.component.Component;
import com.evolveum.midpoint.schrodinger.util.Schrodinger;
+import org.openqa.selenium.Keys;
+
/**
* Created by matus on 3/22/2018.
*/
@@ -21,20 +23,28 @@ public Popover(T parent, SelenideElement parentElement) {
}
public Popover inputValue(String input) {
- getParentElement().$(Schrodinger.byDataId("textInput")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).setValue(input);
+ getDisplayedElement(getParentElement().$$(Schrodinger.byDataId("textInput"))).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).setValue(input);
+
+ return this;
+ }
+ public Popover inputValueWithEnter(String input) {
+ SelenideElement inputField = getDisplayedElement(getParentElement().$$(Schrodinger.byDataId("textInput")));
+ inputField.waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).setValue(input);
+ inputField.sendKeys(Keys.ENTER);
return this;
}
public T updateSearch() {
- getParentElement().$(Schrodinger.byDataId("update")).click();
- getParentElement().$(Schrodinger.byDataId("update")).waitUntil(Condition.disappears, MidPoint.TIMEOUT_DEFAULT_2_S);
+ SelenideElement button = getDisplayedElement(getParentElement().$$(Schrodinger.byDataId("update")));
+ button.click();
+ button.waitUntil(Condition.disappears, MidPoint.TIMEOUT_DEFAULT_2_S);
return this.getParent();
}
public T close() {
- getParentElement().$(Schrodinger.byDataId("close")).click();
+ getDisplayedElement(getParentElement().$$(Schrodinger.byDataId("searchSimple"))).click();
return this.getParent();
}
diff --git a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Search.java b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Search.java
index e51b526335a..cf6402d081a 100644
--- a/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Search.java
+++ b/tools/schrodinger/src/main/java/com/evolveum/midpoint/schrodinger/component/common/Search.java
@@ -9,11 +9,13 @@
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection;
+import com.codeborne.selenide.Selenide;
import com.codeborne.selenide.SelenideElement;
import com.evolveum.midpoint.schrodinger.MidPoint;
import com.evolveum.midpoint.schrodinger.component.Component;
import com.evolveum.midpoint.schrodinger.util.Schrodinger;
+import org.openqa.selenium.By;
/**
* Created by Viliam Repan (lazyman).
@@ -26,25 +28,20 @@ public Search(T parent, SelenideElement parentElement) {
public Popover> byName() {
+ choiceBasicSearch();
+
+ getParentElement().$(Schrodinger.byDataId("a", "mainButton")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).click();
+ Selenide.sleep(2000);
+ return new Popover<>(this, getDisplayedPopover());
+ }
+
+ private void choiceBasicSearch() {
SelenideElement linksContainer = getParentElement().$(Schrodinger.byDataId("div", "linksContainer")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S);
try {
linksContainer.$(Schrodinger.byDataId("a", "basic")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).click();
} catch (Throwable t) {
// all is ok, basic search is already selected option, TODO: Schrodinger should provide easy method to check component existence
}
-
- getParentElement().$(Schrodinger.byDataId("a", "mainButton")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).click();
- ElementsCollection popoverElements = getParentElement().$$(Schrodinger.byDataId("popover"));
-
- SelenideElement popover = null;
- for (SelenideElement popoverElement : popoverElements) {
- if (popoverElement.isDisplayed()) {
- popover = popoverElement;
- break;
- }
- popover = popoverElement;
- }
- return new Popover<>(this, popover);
}
public InputBox> byFullText() {
@@ -60,5 +57,59 @@ public InputBox> byFullText() {
SelenideElement fullTextField = getParentElement().$(Schrodinger.byDataId("input", "fullTextField")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S);
return new InputBox<> (this, fullTextField);
}
+
+ public Search addSearchItem(String name) {
+ choiceBasicSearch();
+ getParentElement().$(Schrodinger.byDataId("a", "more")).waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).click();
+ Selenide.sleep(2000);
+ SelenideElement popover = getDisplayedPopover();
+ popover.$(Schrodinger.byDataId("input", "addText")).setValue(name);
+ Selenide.sleep(2000);
+ popover.$(Schrodinger.byDataId("a", "propLink")).click();
+ return this;
+ }
+
+ public Popover> byItem(String name) {
+
+ choiceBasicSearch();
+
+ SelenideElement item = getItemByName(name);
+ if (item == null) {
+ addSearchItem(name);
+ Selenide.sleep(2000);
+ }
+ item = getItemByName(name);
+ if (item == null) {
+ throw new IllegalStateException("Couldn't find search item for name " + name);
+ }
+
+ item.waitUntil(Condition.appears, MidPoint.TIMEOUT_DEFAULT_2_S).click();
+ Selenide.sleep(2000);
+ return new Popover<>(this, getDisplayedPopover());
+ }
+
+ private SelenideElement getItemByName(String name) {
+ ElementsCollection items = getParentElement().findAll(Schrodinger.byDataId("a", "mainButton"));
+ for (SelenideElement item : items) {
+ if (item.getText().startsWith(name + ":")) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ private SelenideElement getDisplayedPopover() {
+ ElementsCollection popoverElements = getParentElement().$$(Schrodinger.byDataId("popover"));
+ SelenideElement popover = null;
+ for (SelenideElement popoverElement : popoverElements) {
+ if (popoverElement.isDisplayed()) {
+ popover = popoverElement;
+ break;
+ }
+ popover = popoverElement;
+ }
+ return popover;
+ }
+
}