diff --git a/smp-ui-tests/.gitignore b/smp-ui-tests/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..aba821a52f40feef4b488da5a6d3bc35641bc106
--- /dev/null
+++ b/smp-ui-tests/.gitignore
@@ -0,0 +1,21 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# Ignore the drivers
+*.exe
+
+
+.idea/**
+.\src\main\java\Main.java
\ No newline at end of file
diff --git a/smp-ui-tests/README.txt b/smp-ui-tests/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4f1e5a66d13299113fd5984884f34aa719cd93e7
--- /dev/null
+++ b/smp-ui-tests/README.txt
@@ -0,0 +1,36 @@
+This folder contains the Webdriver scripts that test the SMP 4.1.0 UI
+
+Tests could not be written for any functionality that involves uploading files, 
+encountered in Domain and Users page because the select file dialog is a system dialog and not accessible from the browser.
+
+Also there are no tests for Audit functionality because this happens now only in database.
+
+* Setup:
+
+The tests are written in Java so Oracle Java 8 or above and Maven are required.
+To drive the browser ChromeDriver or GekoDriver is required. This can be downloaded from the following locations:
+ChromeDriver - http://chromedriver.storage.googleapis.com/index.html
+GekoDriver - https://github.com/mozilla/geckodriver/releases
+
+After unzipping the path to the executable need to be updated in the pom.xml file
+under "/project/profiles/profile/build/plugins/plugin/configuration/systemPropertyVariables".
+
+In the same set of variables please update the URL for the SMP home page.
+
+* Run:
+
+** Windows:
+mvn clean test -P<profileName>
+
+** Linux:
+To run on Linux command line you need to install "Xvfb" and of course Firefox or Chromium
+(There is a crash when starting Chromium so it is better to run using Firefox until the crash is resolved)
+
+sudo xvfb-run --server-args="-screen 0 1920x1080x24" mvn test -P<profileName>
+
+* Reports
+
+Scripts provide multiple reports like JUnit and Surefire reports 
+but also a custom Excel report in the ./target folder.
+
+For any questions and complains please refer to the creator of these scripts - CATALIN COMANICI
\ No newline at end of file
diff --git a/smp-ui-tests/pom.xml b/smp-ui-tests/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bce9ae6fa7bd9f15370c199402d0865d56b7fad4
--- /dev/null
+++ b/smp-ui-tests/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.test.smp</groupId>
+    <artifactId>SMPUIAutomation</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>1.2.17</version>
+		</dependency>
+		<dependency>
+			<groupId>org.testng</groupId>
+			<artifactId>testng</artifactId>
+			<version>7.0.0-beta1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.seleniumhq.selenium</groupId>
+			<artifactId>selenium-java</artifactId>
+			<version>3.14.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.poi</groupId>
+			<artifactId>poi-ooxml</artifactId>
+			<version>3.17</version>
+		</dependency>
+		<dependency>
+			<groupId>org.reflections</groupId>
+			<artifactId>reflections</artifactId>
+			<version>0.9.11</version>
+		</dependency>
+		<dependency>
+			<groupId>org.json</groupId>
+			<artifactId>json</artifactId>
+			<version>20080701</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.thoughtworks.xstream</groupId>
+			<artifactId>xstream</artifactId>
+			<version>1.4.10</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.sun.jersey</groupId>
+			<artifactId>jersey-client</artifactId>
+			<version>1.19.4</version>
+		</dependency>
+
+
+	</dependencies>
+	<profiles>
+		<profile>
+			<id>smp_e5</id>
+			<activation>
+				<activeByDefault>true</activeByDefault>
+			</activation>
+			<build>
+				<plugins>
+					<plugin>
+						<artifactId>maven-surefire-plugin</artifactId>
+						<version>2.22.1</version>
+						<configuration>
+							<failIfNoTests>true</failIfNoTests>
+							<systemPropertyVariables>
+								<webdriver.chrome.driver>chromedriver.exe</webdriver.chrome.driver>
+								<webdriver.gecko.driver>geckodriver.exe</webdriver.gecko.driver>
+								<reports.folder>./target/</reports.folder>
+								<data.folder>.\src\main\resources\</data.folder>
+								<testdata.file>testData.json</testdata.file>
+								<LONG_TIMEOUT>30</LONG_TIMEOUT>
+								<SHORT_TIMEOUT>5</SHORT_TIMEOUT>
+								<UI_BASE_URL>http://edeltest5.westeurope.cloudapp.azure.com:7003/smp/ui/</UI_BASE_URL>
+							</systemPropertyVariables>
+						</configuration>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+		<profile>
+			<id>ubuntu</id>
+			<activation>
+				<activeByDefault>false</activeByDefault>
+			</activation>
+			<build>
+				<plugins>
+					<plugin>
+						<artifactId>maven-surefire-plugin</artifactId>
+						<version>2.22.1</version>
+						<configuration>
+							<failIfNoTests>true</failIfNoTests>
+
+							<systemPropertyVariables>
+								<webdriver.chrome.driver>chromedriver</webdriver.chrome.driver>
+								<reports.folder>./target/</reports.folder>
+								<data.folder>./src/main/resources/</data.folder>
+								<testdata.file>testData.json</testdata.file>
+								<LONG_TIMEOUT>30</LONG_TIMEOUT>
+								<SHORT_TIMEOUT>15</SHORT_TIMEOUT>
+								<UI_BASE_URL>http://edeltest5.westeurope.cloudapp.azure.com:7003/smp/ui/</UI_BASE_URL>
+							</systemPropertyVariables>
+						</configuration>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+
+	</profiles>
+
+
+
+
+</project>
\ No newline at end of file
diff --git a/smp-ui-tests/src/main/java/pages/components/ConfirmationDialog.java b/smp-ui-tests/src/main/java/pages/components/ConfirmationDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..851d255f398c460231080e4fb86975ae05f04054
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/ConfirmationDialog.java
@@ -0,0 +1,41 @@
+package pages.components;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+public class ConfirmationDialog extends PageComponent {
+
+
+	public ConfirmationDialog(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(id = "yesbuttondialog_id")
+	private WebElement yesBtn;
+
+	@FindBy(id = "nobuttondialog_id")
+	private WebElement noBtn;
+
+	public void confirm(){
+		log.info("dialog .. confirm");
+		waitForElementToBeClickable(yesBtn);
+		yesBtn.click();
+		waitForElementToBeGone(yesBtn);
+
+	}
+
+	public void cancel(){
+		log.info("dialog .. cancel");
+		waitForElementToBeClickable(noBtn);
+		noBtn.click();
+		waitForElementToBeGone(noBtn);
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/GenericSelect.java b/smp-ui-tests/src/main/java/pages/components/GenericSelect.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a409f8d3879b9927f09b29a4f56c6d314c1f6f
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/GenericSelect.java
@@ -0,0 +1,93 @@
+package pages.components;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import pages.components.baseComponents.PageComponent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GenericSelect extends PageComponent {
+	public GenericSelect(WebDriver driver, WebElement container) {
+		super(driver);
+		this.container = container;
+		
+		PageFactory.initElements(new DefaultElementLocatorFactory(container), this);
+	}
+
+	private WebElement container;
+
+	@FindBy(className = "mat-select-arrow")
+	WebElement expandoButton;
+
+	@FindBy(css = "div.mat-select-value span")
+	WebElement curentValueElement;
+
+	private By optionSelector = By.tagName("mat-option");
+
+
+	private void expandSelect(){
+		waitForElementToBeClickable(expandoButton).click();
+	}
+
+	private List<WebElement> getOptions(){
+		expandSelect();
+		return webDriverWait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(optionSelector));
+	}
+
+	public List<String> getOptionTexts(){
+		List<WebElement> options = getOptions();
+		List<String> optionTexts = new ArrayList<>();
+
+		for (WebElement option : options) {
+			optionTexts.add(option.getText().trim());
+		}
+		return optionTexts;
+	}
+
+	public boolean selectOptionWithText(String text){
+		List<WebElement> options = getOptions();
+
+
+		for (WebElement option : options) {
+			if(option.getText().trim().equalsIgnoreCase(text)){
+				waitForElementToBeClickable(option).click();
+				waitForElementToBeGone(option);
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	public String getSelectedValue() {
+		return curentValueElement.getText().trim();
+	}
+
+	public boolean selectOptionByText(String text) {
+		expandoButton.click();
+
+		List<WebElement> options = webDriverWait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(optionSelector));
+		for (WebElement option : options) {
+			String optionDomain = option.getText().trim();
+			if(optionDomain.equalsIgnoreCase(text)){
+				option.click();
+				waitForElementToBeGone(option);
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	public boolean isLoaded() {
+		if(!expandoButton.isDisplayed()){ return false;}
+		if(!curentValueElement.isDisplayed()){ return false;}
+		return true;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/SandwichMenu.java b/smp-ui-tests/src/main/java/pages/components/SandwichMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..94ab2fccc849542e725115e9b07e22d1aecb029f
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/SandwichMenu.java
@@ -0,0 +1,49 @@
+package pages.components;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import pages.service_groups.search.SearchPage;
+import utils.PROPERTIES;
+
+public class SandwichMenu extends PageComponent {
+	public SandwichMenu(WebDriver driver) {
+		super(driver);
+		log.info("sandwich menu init");
+		
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+
+	@FindBy(id = "settingsmenu_id")
+	WebElement expandoButton;
+
+	@FindBy(css = "button[role=\"menuitem\"] span")
+	WebElement currentUserID;
+
+	@FindBy(id = "logout_id")
+	WebElement logoutLnk;
+
+	public boolean isLoggedIn(){
+		waitForElementToBeClickable(expandoButton).click();
+
+		waitForElementToBeVisible(currentUserID);
+		boolean toReturn = !currentUserID.getText().equalsIgnoreCase("Not logged in") ;
+		log.info("User login status is: " + toReturn);
+		currentUserID.click();
+		clickVoidSpace();
+		return toReturn;
+	}
+
+	public SearchPage logout(){
+		waitForElementToBeClickable(expandoButton).click();
+		waitForElementToBeClickable(logoutLnk).click();
+		log.info("Logging out...");
+		return new SearchPage(driver);
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/Sidebar.java b/smp-ui-tests/src/main/java/pages/components/Sidebar.java
new file mode 100644
index 0000000000000000000000000000000000000000..d687dd1f2ee45b4adc934225d50bc7416ffb7288
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/Sidebar.java
@@ -0,0 +1,87 @@
+package pages.components;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.SMPPage;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+import java.security.PublicKey;
+import java.util.List;
+
+public class Sidebar extends PageComponent {
+
+	public Sidebar(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(tagName = "mat-sidenav")
+	private WebElement sideBar;
+
+	private WebElement topLogo;
+	private WebElement topLogoText;
+
+	@FindBy(id = "sidebar_search_id")
+	private WebElement searchLnk;
+
+	@FindBy(id = "sidebar_edit_id")
+	private WebElement editLnk;
+
+	@FindBy(id = "sidebar_domain_id")
+	private WebElement domainLnk;
+
+	@FindBy(id = "sidebar_user_id")
+	private WebElement userLnk;
+
+	/* Receives the Page object class as parameter and based on the class name it navigates to the apropriate page
+	 and returns an instance of that class */
+	public <T extends SMPPage> T goToPage(Class<T> expect){
+		log.info("Navigating to " + expect.getSimpleName());
+		switch (expect.getSimpleName()) {
+			case "SearchPage":
+				waitForElementToBeClickable(searchLnk).click();
+				break;
+			case "EditPage":
+				waitForElementToBeClickable(editLnk).click();
+				break;
+			case "DomainPage":
+				waitForElementToBeClickable(domainLnk).click();
+				break;
+			case "UsersPage":
+				waitForElementToBeClickable(userLnk).click();
+				break;
+		}
+
+		return PageFactory.initElements(driver, expect);
+	}
+
+	public boolean isSearchLnkVisible(){
+		try {
+			return searchLnk.isDisplayed() && searchLnk.isEnabled();
+		} catch (Exception e) {	}
+		return false;
+	}
+	public boolean isEditLnkVisible(){
+		try {
+			return editLnk.isDisplayed() && editLnk.isEnabled();
+		} catch (Exception e) {	}
+		return false;
+	}
+	public boolean isDomainLnkVisible(){
+		try {
+			return domainLnk.isDisplayed() && domainLnk.isEnabled();
+		} catch (Exception e) {	}
+		return false;
+	}
+	public boolean isUsersLnkVisible(){
+		try {
+			return userLnk.isDisplayed() && userLnk.isEnabled();
+		} catch (Exception e) {	}
+		return false;
+	}
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/baseComponents/Header.java b/smp-ui-tests/src/main/java/pages/components/baseComponents/Header.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f2a0e3034730eac80ab78cddab917684bd51e7e
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/baseComponents/Header.java
@@ -0,0 +1,39 @@
+package pages.components.baseComponents;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import pages.components.GenericSelect;
+import pages.components.SandwichMenu;
+import pages.login.LoginPage;
+import utils.PROPERTIES;
+
+public class Header extends PageComponent{
+
+	public Header(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(css = "page-header > h1")
+	private WebElement pageTitle;
+
+	@FindBy(css = ".helpMenu")
+	private WebElement helpLnk;
+
+	@FindBy(css = "#sandwichMenu a")
+	private WebElement loginLnk;
+
+	public SandwichMenu sandwichMenu = new SandwichMenu(driver);
+
+	public LoginPage goToLogin(){
+		waitForElementToBeClickable(loginLnk).click();
+		return new LoginPage(driver);
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/baseComponents/PageComponent.java b/smp-ui-tests/src/main/java/pages/components/baseComponents/PageComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..6756ac78667fcea2fa228207be3e4c3374b80d51
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/baseComponents/PageComponent.java
@@ -0,0 +1,98 @@
+package pages.components.baseComponents;
+
+
+import org.apache.log4j.Logger;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import utils.PROPERTIES;
+
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalUnit;
+import java.util.concurrent.TimeUnit;
+
+
+public class PageComponent {
+
+	protected WebDriver driver;
+	protected WebDriverWait webDriverWait;
+	protected Logger log = Logger.getLogger(this.getClass());
+
+
+	public PageComponent(WebDriver driver) {
+		this.driver = driver;
+		this.webDriverWait = new WebDriverWait(this.driver, PROPERTIES.TIMEOUT);
+	}
+
+	public void waitForXMillis(Integer millis) {
+		try {
+			Thread.sleep(millis);
+		} catch (InterruptedException e) { e.printStackTrace(); }
+	}
+
+	public WebElement waitForElementToBeClickable(WebElement element) {
+		return webDriverWait.until(ExpectedConditions.elementToBeClickable(element));
+	}
+
+	public WebElement waitForElementToBeVisible(WebElement element) {
+		return webDriverWait.until(ExpectedConditions.visibilityOf(element));
+	}
+	
+	public void waitForElementToBeEnabled(WebElement element) {
+		int maxTimeout = PROPERTIES.TIMEOUT * 1000;
+		int waitedSoFar = 0;
+		while ((null != element.getAttribute("disabled")) && (waitedSoFar < maxTimeout)){
+			waitedSoFar += 300;
+			waitForXMillis(300);
+		}
+	}
+
+	public void waitForElementToBeGone(WebElement element) {
+		try {
+			webDriverWait.until(ExpectedConditions.not(ExpectedConditions.visibilityOf(element)));
+		} catch (Exception e) {	}
+	}
+
+	public void waitForNumberOfWindowsToBe(int noOfWindows) {
+		try {
+			webDriverWait.until(numberOfWindowsToBe(noOfWindows));
+		} catch (Exception e) {	}
+	}
+
+	public void clearAndFillInput(WebElement element, String toFill) {
+
+		waitForElementToBeVisible(element).clear();
+		element.sendKeys(toFill);
+	}
+
+	public void clickVoidSpace(){
+		WebElement topLogoText = driver.findElement(By.id("topLogo"));
+		Point logoPoint = topLogoText.getLocation();
+		int x = logoPoint.x;
+		int y = logoPoint.y;
+		new Actions(driver).moveByOffset(x, y).click().build().perform();
+		try {
+			waitForElementToBeGone(driver.findElement(By.cssSelector("[class*=\"overlay-backdrop\"]")));
+		} catch (Exception e) {	}
+		waitForXMillis(500);
+	}
+
+
+	private ExpectedCondition<Boolean> numberOfWindowsToBe(final int numberOfWindows) {
+		return new ExpectedCondition<Boolean>() {
+			@Override
+			public Boolean apply(WebDriver driver) {
+				driver.getWindowHandles();
+				return driver.getWindowHandles().size() == numberOfWindows;
+			}
+		};}
+
+
+}
+
diff --git a/smp-ui-tests/src/main/java/pages/components/baseComponents/PaginationControls.java b/smp-ui-tests/src/main/java/pages/components/baseComponents/PaginationControls.java
new file mode 100644
index 0000000000000000000000000000000000000000..95db12270145af496191f14affa74a97d928312c
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/baseComponents/PaginationControls.java
@@ -0,0 +1,175 @@
+package pages.components.baseComponents;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import pages.components.GenericSelect;
+import pages.components.baseComponents.PageComponent;
+
+import java.util.List;
+
+public class PaginationControls extends PageComponent {
+
+
+	public PaginationControls(WebDriver driver) {
+		super(driver);
+		
+		log.info("initiating pagination controls!");
+		PageFactory.initElements( driver, this);
+		
+		pageSizeSelect = new GenericSelect(driver, pageSizeSelectContainer);
+	}
+
+	@FindBy(css = "li.pages")
+	List<WebElement> pgLinks;
+
+	@FindBy(css = "li.pages.active")
+	WebElement activePageLnk;
+	
+	@FindBy(css = "datatable-footer > div > datatable-pager > ul > li:nth-child(1)")
+	WebElement skipFirstLnk;
+	
+	@FindBy(css = "datatable-footer > div > datatable-pager > ul > li:nth-last-child(1)")
+	WebElement skipLastLnk;
+	
+	@FindBy(css = "datatable-footer > div > datatable-pager > ul > li:nth-last-child(2)")
+	WebElement nextPageLnk;
+	
+	@FindBy(css = "datatable-footer > div > datatable-pager > ul > li:nth-child(2)")
+	WebElement prevPageLnk;
+	
+	
+	@FindBy(id = "pagesize_id")
+	WebElement pageSizeSelectContainer;
+	public GenericSelect pageSizeSelect;
+	
+	@FindBy(css = "datatable-footer > div > div.page-count")
+	WebElement pageCount;
+
+	
+	public boolean hasNextPage(){
+		return !("disabled".equalsIgnoreCase(nextPageLnk.getAttribute("class")));
+	}
+	
+	public int getExpectedNoOfPages(){
+		
+		log.info("getting expected number of pages");
+		
+		int noOfItems = getTotalItems();
+		int itemsPerPg = Integer.valueOf(pageSizeSelect.getSelectedValue());
+		
+		return (int) Math.ceil((double)noOfItems/itemsPerPg);
+	}
+	
+	public int getNoOfItemsOnLastPg(){
+		
+		log.info("getting expected number of items on last page");
+		
+		int noOfItems = getTotalItems();
+		int itemsPerPg = Integer.valueOf(pageSizeSelect.getSelectedValue());
+		
+		return noOfItems%itemsPerPg;
+	}
+	
+	public int getItemsPerPage(){
+		int itemsPerPg = Integer.valueOf(pageSizeSelect.getSelectedValue());
+		
+		log.info("selected value for items per page is .. " + itemsPerPg);
+		
+		return itemsPerPg;
+	}
+	
+	
+	
+	
+	public boolean isPaginationPresent(){
+		log.info("checking if pagination is present on page");
+		return (activePageLnk.isDisplayed());
+	}
+	
+//	if pagination is not present we return 1 by default
+	public Integer getActivePage(){
+		
+		log.info("getting active page number");
+		
+		if(!activePageLnk.isDisplayed()){return 1;}
+		return Integer.valueOf(activePageLnk.getText().trim());
+	}
+	
+	public void goToPage(int pgNo){
+		
+		log.info("going to page .. " + pgNo);
+		
+		for (WebElement pgLink : pgLinks) {
+			if(Integer.valueOf(pgLink.getText().trim()) == pgNo){
+				pgLink.click();
+				PageFactory.initElements(driver, this);
+				return;
+			}
+		}
+	}
+	
+	
+	public void skipToFirstPage(){
+		log.info("skip to FIRST page of results");
+		waitForElementToBeClickable(skipFirstLnk).click();
+		PageFactory.initElements(driver, this);
+	}
+	
+	public void skipToLastPage(){
+		log.info("skip to last page of results");
+		waitForElementToBeClickable(skipLastLnk);
+		skipLastLnk.click();
+		PageFactory.initElements(driver, this);
+	}
+	
+	public void goToNextPage(){
+		log.info("going to next page");
+		nextPageLnk.click();
+		PageFactory.initElements(driver, this);
+	}
+	
+	public void goToPrevPage(){
+		log.info("going to prev page");
+		prevPageLnk.click();
+		PageFactory.initElements(driver, this);
+	}
+	
+	
+	public int getTotalItems() {
+		
+		log.info("getting total number of items to be displayed");
+		
+		String raw = pageCount.getText().trim();
+		if(raw.contains("total")){
+			String[] splits = raw.split("/");
+			for (String split : splits) {
+				if(split.contains("total")){
+					String total = split.replaceAll("\\D", "");
+					return Integer.valueOf(total);
+				}
+			}
+		}
+		return 0;
+	}
+	
+	public Integer getNoOfSelectedItems(){
+		
+		log.info("getting number of selected items in grid");
+		
+		String raw = pageCount.getText().trim();
+		if(raw.contains("selected")){
+			String[] splits = raw.split("/");
+			for (String split : splits) {
+				if(split.contains("selected")){
+					String selected = split.replaceAll("\\D", "");
+					return Integer.valueOf(selected);
+				}
+			}
+		}
+		return null;
+	}
+	
+	
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/baseComponents/SMPPage.java b/smp-ui-tests/src/main/java/pages/components/baseComponents/SMPPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..74950505e606a4490fc17743b6bf3603c455c413
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/baseComponents/SMPPage.java
@@ -0,0 +1,42 @@
+package pages.components.baseComponents;
+
+import org.openqa.selenium.WebDriver;
+import pages.components.Sidebar;
+import pages.components.messageArea.AlertArea;
+
+public class SMPPage extends PageComponent {
+
+	public SMPPage(WebDriver driver) {
+		super(driver);
+	}
+
+	public AlertArea alertArea = new AlertArea(driver);
+
+	public Sidebar sidebar = new Sidebar(driver);
+
+	public Header pageHeader = new Header(driver);
+
+	public void refreshPage(){
+		driver.navigate().refresh();
+	}
+
+	public void screenshotPage(){
+//		try {
+//			File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
+//
+//			OutputStream out = new FileOutputStream(new File("screenshot.png"));
+//
+//
+//
+//			scrFile.createNewFile();
+//			out.write(scrFile);
+//			out.close();
+//		} catch (IOException e) {
+//			e.printStackTrace();
+//		}
+	}
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/grid/BasicGrid.java b/smp-ui-tests/src/main/java/pages/components/grid/BasicGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..661087b65778bb7e8d8169f43e7ffe5af55f2b5a
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/grid/BasicGrid.java
@@ -0,0 +1,68 @@
+package pages.components.grid;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import pages.components.baseComponents.PageComponent;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BasicGrid extends PageComponent {
+
+	public BasicGrid(WebDriver driver, WebElement container) {
+		super(driver);
+		
+		log.info("Loading basic grid");
+		PageFactory.initElements( new DefaultElementLocatorFactory(container) , this);
+
+		for (int i = 0; i < gridHeaders.size(); i++) {
+			headerTxt.add(gridHeaders.get(i).getText().trim());
+		}
+
+	}
+
+	@FindBy(css = "datatable-header div.datatable-row-center datatable-header-cell")
+	protected List<WebElement> gridHeaders;
+
+	@FindBy(css = "datatable-body-row > div.datatable-row-center.datatable-row-group")
+	protected List<WebElement> gridRows;
+	
+	
+	protected ArrayList<String> headerTxt = new ArrayList<String>();
+	
+	public void selectRow(int rowNumber){
+		log.info("selecting row with number ... " + rowNumber);
+		if(rowNumber>=gridRows.size()){return;}
+		gridRows.get(rowNumber).click();
+	}
+	
+	public void doubleClickRow(int rowNumber){
+		
+		log.info("double clicking row ... " + rowNumber);
+		waitForXMillis(500);
+		if(rowNumber>=gridRows.size()){return ;}
+		Actions action = new Actions(driver);
+		action.doubleClick(gridRows.get(rowNumber)).perform();
+	}
+
+	public int getColumnsNo(){
+		log.info("getting number of columns");
+		return gridHeaders.size();
+	}
+
+	public int getRowsNo(){
+		return gridRows.size();
+	}
+	
+
+	
+	
+	
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/messageArea/AlertArea.java b/smp-ui-tests/src/main/java/pages/components/messageArea/AlertArea.java
new file mode 100644
index 0000000000000000000000000000000000000000..b441529593962459643ace12ca61791eda7a9ff7
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/messageArea/AlertArea.java
@@ -0,0 +1,39 @@
+package pages.components.messageArea;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import utils.PROPERTIES;
+import pages.components.baseComponents.PageComponent;
+
+public class AlertArea  extends PageComponent {
+
+	public AlertArea(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(id = "alertmessage_id")
+	private WebElement alertMessage;
+
+	@FindBy(css = "#alertmessage_id span")
+	private WebElement closeAlertSpan;
+
+	public AlertMessage getAlertMessage(){
+		if(!alertMessage.isDisplayed()){
+			log.warn("No messages displayed.");
+			return null;
+		}
+
+		String rawMessTxt = alertMessage.getText().replaceAll("\\n", "").trim();
+		String closeChr = closeAlertSpan.getText();
+		String messageTxt = rawMessTxt.replaceAll(closeChr, "").trim();
+
+		log.info("Getting alert messsage ...");
+		return new AlertMessage(messageTxt, alertMessage.getAttribute("class").contains("error"));
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/components/messageArea/AlertMessage.java b/smp-ui-tests/src/main/java/pages/components/messageArea/AlertMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2442e3ac7235c96c94ee98a8a71551747ca6d01
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/components/messageArea/AlertMessage.java
@@ -0,0 +1,28 @@
+package pages.components.messageArea;
+
+public class AlertMessage {
+
+	String message;
+	boolean isError;
+
+	public AlertMessage(String message, boolean isError) {
+		this.message = message;
+		this.isError = isError;
+	}
+
+	public String getMessage() {
+		return message.replaceAll("×", "").trim();
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public boolean isError() {
+		return isError;
+	}
+
+	public void setError(boolean error) {
+		isError = error;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/domain/DomainGrid.java b/smp-ui-tests/src/main/java/pages/domain/DomainGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..41b3458f54beb9b4caae5bd791b8d71e3214e92a
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/domain/DomainGrid.java
@@ -0,0 +1,39 @@
+package pages.domain;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import pages.components.grid.BasicGrid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DomainGrid extends BasicGrid {
+	public DomainGrid(WebDriver driver, WebElement container) {
+		super(driver, container);
+	}
+	
+	private By cellSelector = By.tagName("datatable-body-cell");
+	
+	public List<DomainRow> getRowsInfo(){
+		List<DomainRow> rowInfos = new ArrayList<>();
+		
+		for (WebElement gridRow : gridRows) {
+			List<WebElement> cells = gridRow.findElements(cellSelector);
+			
+			DomainRow row = new DomainRow();
+			row.setDomainCode(cells.get(0).getText().trim());
+			row.setSmlDomain(cells.get(1).getText().trim());
+			row.setSmlSmpID(cells.get(2).getText().trim());
+			row.setClientCertHeader(cells.get(3).getText().trim());
+			row.setClientCertAlias(cells.get(4).getText().trim());
+			row.setClientCertAlias(cells.get(5).getText().trim());
+			row.setSignatureCertAlias(cells.get(6).getText().trim());
+			
+			rowInfos.add(row);
+		}
+		
+		return rowInfos;
+	}
+	
+}
diff --git a/smp-ui-tests/src/main/java/pages/domain/DomainPage.java b/smp-ui-tests/src/main/java/pages/domain/DomainPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..7228a9e0d5b9c943a56b3a247bf50ad4dda5c140
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/domain/DomainPage.java
@@ -0,0 +1,106 @@
+package pages.domain;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.PaginationControls;
+import pages.components.baseComponents.SMPPage;
+import pages.components.grid.BasicGrid;
+import pages.users.UserPopup;
+import utils.PROPERTIES;
+
+public class DomainPage extends SMPPage {
+	public DomainPage(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+	
+	@FindBy(id = "searchTable")
+	private WebElement domainTableContainer;
+	
+	@FindBy(id = "cancelButton")
+	private WebElement cancelBtn;
+	
+	@FindBy(id = "saveButton")
+	private WebElement saveBtn;
+	
+	@FindBy(id = "newButton")
+	private WebElement newBtn;
+	
+	@FindBy(id = "editButton")
+	private WebElement editBtn;
+	
+	@FindBy(id = "deleteButton")
+	private WebElement deleteBtn;
+
+	public PaginationControls pagination = new PaginationControls(driver);
+	
+	
+	
+	public boolean isLoaded(){
+
+		waitForElementToBeVisible(newBtn);
+
+		if(!cancelBtn.isDisplayed()){return false;}
+		if(!saveBtn.isDisplayed()){return false;}
+		if(!newBtn.isDisplayed()){return false;}
+		if(!newBtn.isEnabled()){return false;}
+		if(!editBtn.isDisplayed()){return false;}
+		if(!deleteBtn.isDisplayed()){return false;}
+		
+		return true;
+	}
+	
+	public boolean isCancelButtonEnabled(){
+		return cancelBtn.isEnabled();
+	}
+	public boolean isSaveButtonEnabled(){
+		return saveBtn.isEnabled();
+	}
+	public boolean isDeleteButtonEnabled(){
+		return deleteBtn.isEnabled();
+	}
+	public boolean isEditButtonEnabled(){
+		return editBtn.isEnabled();
+	}
+	public boolean isNewButtonEnabled(){
+		return newBtn.isEnabled();
+	}
+	
+	public ConfirmationDialog clickCancel(){
+		waitForElementToBeClickable(cancelBtn).click();
+		return new ConfirmationDialog(driver);
+	}
+	
+	public ConfirmationDialog clickSave(){
+		waitForElementToBeClickable(saveBtn).click();
+		return new ConfirmationDialog(driver);
+	}
+	
+	public void clickDelete(){
+		waitForElementToBeClickable(deleteBtn).click();
+	}
+	public DomainPopup clickNew(){
+		waitForElementToBeClickable(newBtn).click();
+		return new DomainPopup(driver);
+	}
+	public DomainPopup clickEdit(){
+		waitForElementToBeClickable(editBtn).click();
+		return new DomainPopup(driver);
+	}
+	
+	
+	public DomainGrid grid(){
+		return new DomainGrid(driver, domainTableContainer);
+	}
+	
+	
+	
+	
+	
+	
+	
+}
diff --git a/smp-ui-tests/src/main/java/pages/domain/DomainPopup.java b/smp-ui-tests/src/main/java/pages/domain/DomainPopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..19477bb50af0d74701a54ae7a612d8be69283f4b
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/domain/DomainPopup.java
@@ -0,0 +1,101 @@
+package pages.domain;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+public class DomainPopup extends PageComponent {
+	public DomainPopup(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+	
+	@FindBy(css = "domain-details-dialog > table > tbody > tr > td > button:nth-child(1)")
+	WebElement okBtn;
+	
+	@FindBy(css = "domain-details-dialog > table > tbody > tr > td > button:nth-child(2)")
+	WebElement cancelBtn;
+	
+	@FindBy(css = "#domainCode_id")
+	WebElement domainCodeInput;
+	
+	@FindBy(css = "#smldomain_id")
+	WebElement smldomainInput;
+	
+	@FindBy(css = "#signatureKeyAlias_id")
+	WebElement responseSignatureCertInput;
+
+	@FindBy(css = "#smlSMPId_id")
+	WebElement smlSMPIdInput;
+	
+	@FindBy(css = "#smlClientHeader_id")
+	WebElement smlClientHeaderInput;
+	
+	@FindBy(css = "#smlClientKeyAlias_id")
+	WebElement smlClientKeyAliasInput;
+
+	public void clickOK(){
+		waitForElementToBeClickable(okBtn).click();
+		waitForElementToBeGone(okBtn);
+	}
+	public void clickCancel() {
+		waitForElementToBeClickable(cancelBtn).click();
+		waitForElementToBeGone(cancelBtn);
+	}
+	
+	public boolean isLoaded() {
+		waitForElementToBeVisible(okBtn);
+		if(!okBtn.isDisplayed()){return false;}
+		if(!domainCodeInput.isDisplayed()){return false;}
+		if(!smldomainInput.isDisplayed()){return false;}
+		if(!responseSignatureCertInput.isDisplayed()){return false;}
+		if(!smlClientHeaderInput.isDisplayed()){return false;}
+		if(!smlClientKeyAliasInput.isDisplayed()){return false;}
+		if(!cancelBtn.isDisplayed() || !cancelBtn.isEnabled()){return false;}
+		
+		return true;
+	}
+
+	public boolean isOKButtonEnabled() {return waitForElementToBeVisible(okBtn).isEnabled();}
+	public boolean isCancelButtonEnabled() {return waitForElementToBeVisible(cancelBtn).isEnabled();}
+
+	public boolean isDomainCodeInputEnabled() {return waitForElementToBeVisible(domainCodeInput).isEnabled();}
+	public boolean isSMLDomainInputEnabled() {return waitForElementToBeVisible(smldomainInput).isEnabled();}
+	public boolean isResponseSignatureCertInputEnabled() {return waitForElementToBeVisible(responseSignatureCertInput).isEnabled();}
+
+	public boolean isSMLSMPIdInputEnabled() {return waitForElementToBeVisible(smlSMPIdInput).isEnabled();}
+	public boolean isSMLClientHeaderEnabled() {return waitForElementToBeVisible(smlClientHeaderInput).isEnabled();}
+	public boolean isSMLClientKeyAliasInputEnabled() {return waitForElementToBeVisible(smlClientKeyAliasInput).isEnabled();}
+
+
+	public void fillResponseSignatureCertInput(String text){
+		clearAndFillInput(responseSignatureCertInput, text);
+	}
+	public void fillSMLSMPIdInput(String text){
+		waitForXMillis(500);
+		clearAndFillInput(smlSMPIdInput, text);
+	}
+	public void fillSMLClientHeader(String text){
+		clearAndFillInput(smlClientHeaderInput, text);
+	}
+	public void fillSMLClientKeyAliasInput(String text){
+		clearAndFillInput(smlClientKeyAliasInput, text);
+	}
+
+	public void fillDataForNewDomain(String domainCode, String smlDomain, String responseSignature, String smlSmpID, String clientCertHeader, String certAlias){
+		clearAndFillInput(domainCodeInput, domainCode);
+		clearAndFillInput(smldomainInput, smlDomain);
+		clearAndFillInput(responseSignatureCertInput, responseSignature);
+		clearAndFillInput(smlSMPIdInput, smlSmpID);
+		clearAndFillInput(smlClientHeaderInput, clientCertHeader);
+		clearAndFillInput(smlClientKeyAliasInput, certAlias);
+
+	}
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/domain/DomainRow.java b/smp-ui-tests/src/main/java/pages/domain/DomainRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..01c339ecd166a4d855faf1ccefd534c989fc192c
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/domain/DomainRow.java
@@ -0,0 +1,90 @@
+package pages.domain;
+
+public class DomainRow{
+
+	private String domainCode;
+	private String smlDomain;
+	private String smlSmpID;
+	private String clientCertHeader;
+	private String clientCertAlias;
+	private String signatureCertAlias;
+	
+	
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+		
+		DomainRow row = (DomainRow) o;
+		
+		if (domainCode != null ? !domainCode.equals(row.domainCode) : row.domainCode != null) return false;
+		if (smlDomain != null ? !smlDomain.equals(row.smlDomain) : row.smlDomain != null) return false;
+		if (smlSmpID != null ? !smlSmpID.equals(row.smlSmpID) : row.smlSmpID != null) return false;
+		if (clientCertHeader != null ? !clientCertHeader.equals(row.clientCertHeader) : row.clientCertHeader != null)
+			return false;
+		if (clientCertAlias != null ? !clientCertAlias.equals(row.clientCertAlias) : row.clientCertAlias != null)
+			return false;
+		return signatureCertAlias != null ? signatureCertAlias.equals(row.signatureCertAlias) : row.signatureCertAlias == null;
+	}
+	
+	
+	@Override
+	public String toString() {
+		return "DomainRow{" +
+				"domainCode='" + domainCode + '\'' +
+				", smlDomain='" + smlDomain + '\'' +
+				", smlSmpID='" + smlSmpID + '\'' +
+				", clientCertHeader='" + clientCertHeader + '\'' +
+				", clientCertAlias='" + clientCertAlias + '\'' +
+				", signatureCertAlias='" + signatureCertAlias + '\'' +
+				'}';
+	}
+	
+	public String getDomainCode() {
+		return domainCode;
+	}
+	
+	public void setDomainCode(String domainCode) {
+		this.domainCode = domainCode;
+	}
+	
+	public String getSmlDomain() {
+		return smlDomain;
+	}
+	
+	public void setSmlDomain(String smlDomain) {
+		this.smlDomain = smlDomain;
+	}
+	
+	public String getSmlSmpID() {
+		return smlSmpID;
+	}
+	
+	public void setSmlSmpID(String smlSmpID) {
+		this.smlSmpID = smlSmpID;
+	}
+	
+	public String getClientCertHeader() {
+		return clientCertHeader;
+	}
+	
+	public void setClientCertHeader(String clientCertHeader) {
+		this.clientCertHeader = clientCertHeader;
+	}
+	
+	public String getClientCertAlias() {
+		return clientCertAlias;
+	}
+	
+	public void setClientCertAlias(String clientCertAlias) {
+		this.clientCertAlias = clientCertAlias;
+	}
+	
+	public String getSignatureCertAlias() {
+		return signatureCertAlias;
+	}
+	
+	public void setSignatureCertAlias(String signatureCertAlias) {
+		this.signatureCertAlias = signatureCertAlias;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/login/LoginPage.java b/smp-ui-tests/src/main/java/pages/login/LoginPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b9fbe6b3183466591d93378e82866ce3fc319ca
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/login/LoginPage.java
@@ -0,0 +1,114 @@
+package pages.login;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.SMPPage;
+import pages.service_groups.search.SearchPage;
+import utils.PROPERTIES;
+import utils.TestDataProvider;
+
+import java.util.HashMap;
+
+public class LoginPage extends SMPPage {
+
+	public LoginPage(WebDriver driver) {
+		super(driver);
+		
+		log.info(".... init");
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(id = "username_id")
+	private WebElement username;
+
+	@FindBy(id = "password_id")
+	private WebElement password;
+
+	@FindBy(id = "loginbutton_id")
+	private WebElement loginBtn;
+
+	@FindBy(className = "smpVersion")
+	private WebElement smpVersion;
+
+	public boolean isLoaded(){
+		
+		log.info("check if is loaded");
+		
+		if(!username.isEnabled()){
+			log.error("Could not find username input!");
+			return false;
+		}
+		if(!password.isEnabled()){
+			log.error("Could not find password input!");
+			return false;
+		}
+		if(!loginBtn.isDisplayed()){
+			log.error("Could not find login button!");
+			return false;
+		}
+
+		if(!smpVersion.isDisplayed()){
+			log.error("Could not find version text!");
+			return false;
+		}
+		log.info("Login page controls loaded!");
+		return true;
+	}
+
+	public <T extends SMPPage> T login(String user, String pass, Class<T> expect){
+		log.info("Login started!!");
+		username.clear();
+		username.sendKeys(user);
+		password.clear();
+		password.sendKeys(pass);
+		loginBtn.click();
+
+		log.info("Login action done!");
+
+		return PageFactory.initElements(driver, expect);
+	}
+	
+	public SearchPage login(String user, String pass){
+		log.info("Login started!!");
+
+		clearAndFillInput(username, user);
+		clearAndFillInput(password, pass);
+
+		loginBtn.click();
+
+		log.info("Login action done!");
+
+		return new SearchPage(driver);
+	}
+
+	public SearchPage login(String role){
+		log.info("Login started!!");
+
+		HashMap<String, String> user = new TestDataProvider().getUserWithRole(role);
+
+		clearAndFillInput(username, user.get("username"));
+		clearAndFillInput(password, user.get("password"));
+
+		loginBtn.click();
+
+		log.info("Login action done!");
+
+		return new SearchPage(driver);
+	}
+
+
+	public String getListedSMPVersion(){
+		return waitForElementToBeVisible(smpVersion).getText().trim();
+	}
+
+	public String getTextInUsernameInput(){
+		return waitForElementToBeVisible(username).getText().trim();
+	}
+
+	public String getTextInPasswordInput(){
+		return waitForElementToBeVisible(password).getText().trim();
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/FilterArea.java b/smp-ui-tests/src/main/java/pages/service_groups/FilterArea.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e66a94f036c7362d1dbaa84de9da8dc79745d5c
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/FilterArea.java
@@ -0,0 +1,74 @@
+package pages.service_groups;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import pages.components.GenericSelect;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+public class FilterArea extends PageComponent {
+	public FilterArea(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+
+		domainSelect = new GenericSelect(driver, domainSelectContainer);
+
+	}
+
+
+	@FindBy(id = "participantIdentifier")
+	private WebElement participantIdentifierInput;
+
+	@FindBy(id = "participantScheme")
+	private WebElement participantSchemeInput;
+
+	@FindBy(id = "domain_id")
+	private WebElement domainSelectContainer;
+	public GenericSelect domainSelect;
+
+	@FindBy(id = "searchbutton_id")
+	private WebElement searchButton;
+
+
+
+	public String getParticipantIdentifierInputValue() {
+		return participantIdentifierInput.getText().trim();
+	}
+
+	public String getParticipantSchemeInputValue() {
+		return participantSchemeInput.getText().trim();
+	}
+
+	public boolean isLoaded(){
+		if(!participantIdentifierInput.isDisplayed()){
+			return false;
+		}
+		if(!participantSchemeInput.isDisplayed()){
+			return false;
+		}
+		if(!domainSelect.isLoaded()){
+			return false;
+		}
+		return true;
+	}
+
+	public void filter(String identifier, String scheme, String domain){
+		clearAndFillInput(participantIdentifierInput, identifier);
+		clearAndFillInput(participantSchemeInput, scheme);
+
+		if(null != domain && !domain.isEmpty()){
+			domainSelect.selectOptionByText(domain);
+		}
+
+		searchButton.click();
+//		TODO - wait for loading bar to disappear
+		waitForXMillis(1000);
+
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/MetadataGrid.java b/smp-ui-tests/src/main/java/pages/service_groups/MetadataGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..04f6bed463d81bb2bdb01ba4f3b7cbc0a7d18713
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/MetadataGrid.java
@@ -0,0 +1,30 @@
+package pages.service_groups;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import pages.components.baseComponents.PageComponent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MetadataGrid  extends PageComponent{
+	public MetadataGrid(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( driver, this);
+	}
+
+
+	@FindBy(css = "ngx-datatable.inner-table.virtualized datatable-row-wrapper")
+	List<WebElement> rowContainers;
+
+	public List<MetadataRow> getMetadataRows(){
+		List<MetadataRow> rowList = new ArrayList<>();
+		for (WebElement rowContainer : rowContainers) {
+			rowList.add(new MetadataRow(driver, rowContainer));
+		}
+		return rowList;
+	}
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/MetadataRow.java b/smp-ui-tests/src/main/java/pages/service_groups/MetadataRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d02e6d95981a675faaaefd980207a5621e1167b
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/MetadataRow.java
@@ -0,0 +1,42 @@
+package pages.service_groups;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+
+import java.util.List;
+
+public class MetadataRow extends PageComponent {
+	public MetadataRow(WebDriver driver, WebElement container) {
+			super(driver);
+			PageFactory.initElements( new DefaultElementLocatorFactory(container) , this);
+	}
+
+	@FindBy(tagName = "datatable-body-cell")
+	protected List<WebElement> cells;
+
+	public String getDomain(){
+		return cells.get(0).getText().trim();
+	}
+
+	public String getDocumentIdentifierScheme(){
+		return cells.get(1).getText().trim();
+	}
+
+	public String getDocumentIdentifier(){
+		return cells.get(2).getText().trim();
+	}
+
+	public String getURL(){
+		return cells.get(3).findElement(By.tagName("a")).getAttribute("href").trim();
+	}
+
+	public void clickURL(){
+		cells.get(3).findElement(By.tagName("a")).click();
+	}
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupGrid.java b/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc6505b04fa4d00186e748bd2c25a24b65d1cd46
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupGrid.java
@@ -0,0 +1,95 @@
+package pages.service_groups;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ServiceGroupGrid extends PageComponent {
+
+	public ServiceGroupGrid(WebDriver driver, WebElement container) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(container, PROPERTIES.TIMEOUT) , this);
+	}
+
+	@FindBy(className = "datatable-header-cell-label")
+	List<WebElement> headers;
+
+	@FindBy(className = "datatable-row-wrapper")
+	List<WebElement> rowWrappers;
+
+	public List<ServiceGroupRow> getRows() {
+		List<ServiceGroupRow> rows = new ArrayList<>();
+
+		for (WebElement rowWrapper : rowWrappers) {
+			rows.add(new ServiceGroupRow(driver, rowWrapper));
+		}
+
+		return rows;
+	}
+
+	public boolean isLoaded(){
+		if(headers.size()>0){
+			return true;
+		}
+		return false;
+	}
+
+	public void doubleClickRow(int rowNumber) {
+		log.info("double clicking row ... " + rowNumber);
+		waitForXMillis(500);
+		if(rowNumber>=rowWrappers.size()){return ;}
+		waitForElementToBeClickable(rowWrappers.get(rowNumber));
+		Actions action = new Actions(driver);
+		action.doubleClick(rowWrappers.get(rowNumber)).perform();
+	}
+
+	public void selectRow(int rowNumber) {
+		log.info("clicking row ... " + rowNumber);
+		waitForXMillis(500);
+		if(rowNumber>=rowWrappers.size()){return ;}
+		rowWrappers.get(rowNumber).click();
+	}
+
+	public List<String> getHeaders(){
+		List<String> stHeaders = new ArrayList<>();
+		for (WebElement header : headers) {
+			stHeaders.add(header.getText().trim());
+		}
+		return stHeaders;
+	}
+
+	public int getRowsNo(){
+		return rowWrappers.size();
+	}
+
+
+	public <T extends ServiceGroupRow> ArrayList<T> getRowsAs(Class<T> expectedType){
+		log.info("getting rows!!!");
+		ArrayList<T> toReturn = new ArrayList<T>();
+
+		for (int i = 0; i < rowWrappers.size(); i++) {
+			Constructor<T> constructor = null;
+			T obj = null;
+			try {
+				constructor = expectedType.getDeclaredConstructor(WebDriver.class, WebElement.class);
+				obj = constructor.newInstance(driver, rowWrappers.get(i));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			toReturn.add(obj);
+		}
+		return toReturn;
+	}
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupRow.java b/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..3802f3d04bcf75a208cd5cc4c0062da1e3f07ca3
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/ServiceGroupRow.java
@@ -0,0 +1,73 @@
+package pages.service_groups;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+
+import java.util.List;
+
+public class ServiceGroupRow extends PageComponent {
+
+	public ServiceGroupRow(WebDriver driver, WebElement container) {
+		super(driver);
+		PageFactory.initElements( new DefaultElementLocatorFactory(container) , this);
+	}
+
+
+//	private WebElement container;
+
+	@FindBy(tagName = "datatable-body-cell")
+	protected List<WebElement> cells;
+
+	@FindBy(className = "table-button-expand")
+	private WebElement expandMetadata;
+
+
+	public MetadataGrid expandMetadata() {
+		if(expandMetadata.getText().contains("+")){
+			expandMetadata.click();
+//		todo: find something better to wait for
+			waitForXMillis(1000);}
+		return new MetadataGrid(driver);
+	}
+	public void collapseMetadata(){
+		if(expandMetadata.getText().contains("-")){
+			expandMetadata.click();
+		}
+	}
+
+	public Integer getMetadataSize() {
+		return Integer.valueOf(cells.get(2).getText().trim());
+	}
+
+	public String getParticipantScheme() {
+		return cells.get(3).getText().trim();
+	}
+
+	public String getParticipantIdentifier() {
+		return cells.get(4).getText().trim();
+	}
+
+	public String getServiceGroupURL() {
+		return cells.get(5).findElement(By.tagName("a")).getAttribute("href").trim();
+	}
+
+	public String getExpandButtonText() {
+		return expandMetadata.getText().trim();
+	}
+
+	public boolean isMetadataExpanded() {
+		try{
+			if(	new MetadataGrid(driver).getMetadataRows().size() >0 ){
+				return true;
+			}
+		}catch (Exception e){ e.printStackTrace();}
+		return false;
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/AcordionSection.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/AcordionSection.java
new file mode 100644
index 0000000000000000000000000000000000000000..36a449a9b862f2acf404a2bd57256a33fab8d980
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/AcordionSection.java
@@ -0,0 +1,93 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AcordionSection extends PageComponent {
+	public AcordionSection(WebDriver driver, WebElement container) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(container, PROPERTIES.TIMEOUT) , this);
+	}
+
+	@FindBy(css = "span.mat-content > mat-panel-title")
+	WebElement title;
+
+	@FindBy(css = "span.mat-content > mat-panel-description > div")
+	WebElement selectCount;
+
+
+	@FindBy(css = ".mat-expansion-indicator")
+	WebElement expandButton;
+
+	@FindBy(tagName = "mat-list-option")
+	List<WebElement> options;
+
+	public boolean isExpanded(){
+		return options.get(0).isDisplayed();
+	}
+
+	public String getTitle(){
+		return title.getText().replaceAll("\\W", "").trim();
+	}
+	public String getSelectedCountFullText(){
+		return selectCount.getText().trim();
+	}
+	public Integer getSelectedCount(){
+		String fullText = getSelectedCountFullText();
+		return Integer.valueOf(fullText.replaceAll("\\D", ""));
+	}
+	public void expandSection(){
+		waitForElementToBeClickable(expandButton).click();
+		waitForElementToBeVisible(options.get(0));
+	}
+
+	public void selectOptionWithText(String text){
+		for (WebElement option : options) {
+
+			if(option.getAttribute("aria-selected").contains("true")){continue;}
+
+			if(option.getText().trim().equalsIgnoreCase(text)){
+				option.click();
+				return;
+			}
+		}
+	}
+
+	public void selectOptionWithIndex(Integer index){
+		if(index>=options.size()){return;}
+
+		WebElement option = options.get(index);
+		if(option.getAttribute("aria-selected").contains("true")){return;}
+
+		option.click();
+		return;
+	}
+
+	public boolean optionsEnabled(){
+		waitForElementToBeVisible(title);
+		boolean isDisabled = options.get(0).getAttribute("aria-disabled").equalsIgnoreCase("true");
+		return !isDisabled;
+	}
+
+	public List<String> getOptions(){
+		List<String> optionStr = new ArrayList<>();
+		for (WebElement option : options) {
+			optionStr.add(option.getText().trim());
+		}
+		return optionStr;
+	}
+
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/EditPage.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/EditPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f0f7bd9d0eee1d3e4efc9dba2e01971315a1a75
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/EditPage.java
@@ -0,0 +1,152 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.SMPPage;
+import pages.service_groups.FilterArea;
+import pages.service_groups.ServiceGroupGrid;
+import utils.PROPERTIES;
+
+import java.util.List;
+
+public class EditPage extends SMPPage {
+	public EditPage(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+		filterArea = new FilterArea(driver);
+	}
+
+
+	public FilterArea filterArea;
+
+	@FindBy(id = "searchTable")
+	private WebElement searchTable;
+
+	@FindBy(id = "cancelButton")
+	private WebElement cancelButton;
+
+	@FindBy(id = "saveButton")
+	private WebElement saveButton;
+
+	@FindBy(id = "newButton")
+	private WebElement newButton;
+
+	@FindBy(id = "editButton")
+	private WebElement editButton;
+
+	@FindBy(id = "deleteButton")
+	private WebElement deleteButton;
+
+	public boolean isCancelButtonEnabled(){
+		return cancelButton.isEnabled();
+	}
+	public boolean isSaveButtonEnabled(){
+		return saveButton.isEnabled();
+	}
+	public boolean isDeleteButtonEnabled(){
+		return deleteButton.isEnabled();
+	}
+	public boolean isEditButtonEnabled(){
+		return editButton.isEnabled();
+	}
+	public boolean isNewButtonEnabled(){	return newButton.isEnabled();	}
+
+
+	public ServiceGroupPopup clickEdit(){
+		if(!isEditButtonEnabled()){return null;}
+
+		editButton.click();
+
+		return new ServiceGroupPopup(driver);
+
+	}
+
+	public ServiceGroupPopup clickNew(){
+		waitForElementToBeClickable(newButton).click();
+		return new ServiceGroupPopup(driver);
+	}
+	public ConfirmationDialog clickSave(){
+		waitForElementToBeClickable(saveButton).click();
+		return new ConfirmationDialog(driver);
+	}
+
+	public ConfirmationDialog clickCancel(){
+		waitForElementToBeClickable(cancelButton).click();
+		return new ConfirmationDialog(driver);
+	}
+
+	public void clickDelete(){
+		waitForElementToBeClickable(deleteButton).click();
+	}
+
+	public boolean isNewButtonPresent(){
+		try {
+			return waitForElementToBeVisible(newButton).isDisplayed();
+		} catch (Exception e) {	}
+		return false;
+	}
+
+	public boolean isDeleteButtonPresent(){
+		try {
+			return waitForElementToBeVisible(deleteButton).isDisplayed();
+		} catch (Exception e) {	}
+		return false;
+	}
+
+
+	public ServiceGroupGrid getGrid(){
+		ServiceGroupGrid grid = new ServiceGroupGrid(driver, searchTable);
+		return grid;
+	}
+
+
+	public void addNewSerivceGroup(String identifier, String scheme, List<String> owners, List<String> domains, String extension) {
+		waitForElementToBeClickable(newButton).click();
+
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+		popup.fillForm(identifier, scheme, owners, domains, extension);
+		popup.clickOK();
+
+	}
+
+	public void saveChanges(){
+		waitForElementToBeClickable(saveButton).click();
+		new ConfirmationDialog(driver).confirm();
+
+	}
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataRowE.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataRowE.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b91f23525cc81dc0345e70322fc74de9c5dc6e3
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataRowE.java
@@ -0,0 +1,38 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import pages.service_groups.MetadataRow;
+
+import java.util.List;
+
+public class MetadataRowE extends MetadataRow {
+
+	public MetadataRowE(WebDriver driver, WebElement container) {
+		super(driver, container);
+	}
+
+	@FindBy(css = "datatable-body-cell:nth-child(5) > div > div > button:nth-child(1)")
+	WebElement editMetadataButton;
+
+	@FindBy(css = "datatable-body-cell:nth-child(5) > div > div > button:nth-child(2)")
+	WebElement deleteMetadataButton;
+
+	public void clickEdit(){
+		waitForElementToBeClickable(editMetadataButton).click();
+	}
+
+	public void clickDelete(){
+		waitForElementToBeClickable(deleteMetadataButton).click();
+	}
+
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataWizardPopup.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataWizardPopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..c4ddf634ca05013bd4ef5de48996de14109f01a0
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/MetadataWizardPopup.java
@@ -0,0 +1,64 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.Generator;
+import utils.PROPERTIES;
+
+public class MetadataWizardPopup extends PageComponent {
+	public MetadataWizardPopup(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+	@FindBy(css = "#ExtensionID_id")
+	private WebElement extensionIDInput;
+
+	@FindBy(css = "#ExtensionName_id")
+	private WebElement extensionNameInput;
+
+	@FindBy(css = "#ExtensionAgencyID_id")
+	private WebElement extensionAgencyIDInput;
+
+	@FindBy(css = "#ExtensionAgencyName_id")
+	private WebElement extensionAgencyNameInput;
+
+	@FindBy(css = "#ExtensionAgencyURI_id")
+	private WebElement extensionAgencyURIInput;
+
+	@FindBy(css = "#ExtensionVersionID_id")
+	private WebElement extensionVersionIDInput;
+
+	@FindBy(css = "#ExtensionURI_id")
+	private WebElement eExtensionURIInput;
+
+	@FindBy(css = "#ExtensionReasonCode_id")
+	private WebElement extensionReasonCodeInput;
+
+	@FindBy(css = "#ExtensionReason_id")
+	private WebElement extensionReasonInput;
+
+	@FindBy(css = "service-group-metadata-wizard > mat-dialog-actions > div > button:nth-child(1)")
+	private WebElement okButton;
+
+	public void fillWithRndStrings(){
+		clearAndFillInput(extensionIDInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionNameInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionAgencyIDInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionAgencyNameInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionAgencyURIInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionVersionIDInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(eExtensionURIInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionReasonCodeInput, Generator.randomAlphaNumeric(10));
+		clearAndFillInput(extensionReasonInput, Generator.randomAlphaNumeric(10));
+		okButton.click();
+		waitForElementToBeGone(okButton);
+	}
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupPopup.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupPopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..70c6094469ae660fe87c8ee9c616ae126278374e
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupPopup.java
@@ -0,0 +1,172 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+import java.util.List;
+
+public class ServiceGroupPopup extends PageComponent {
+	public ServiceGroupPopup(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+
+		try {
+			ownersPanel = new AcordionSection(driver, ownersPanelContainer);
+		} catch (Exception e) {
+
+		}
+		domainsPanel = new AcordionSection(driver, domainsPanelContainer);
+
+	}
+
+	@FindBy(css = "#owner_expansion_panel_id")
+	private WebElement ownersPanelContainer;
+	public AcordionSection ownersPanel;
+
+	@FindBy(css = "#domain_expansion_panel_id")
+	private WebElement domainsPanelContainer;
+	public AcordionSection domainsPanel;
+
+	@FindBy(css = "mat-dialog-actions > div > button:nth-child(1)")
+	private WebElement okButton;
+
+	@FindBy(css = "mat-dialog-actions > div > button:nth-child(2)")
+	private WebElement cancelButton;
+
+	@FindBy(css = "#participantIdentifier_id")
+	private WebElement participantIdentifierInput;
+
+	@FindBy(css = "#participantScheme_id")
+	private WebElement participantSchemeInput;
+
+	@FindBy(css = "#extensionTextArea")
+	private WebElement extensionTextArea;
+
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(1)")
+	private WebElement clearExtensionButton;
+
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(2)")
+	private WebElement extensionWizardButton;
+
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(3)")
+	private WebElement validateExtensionButton;
+
+	@FindBy(css = "mat-card-content > div > div.ng-star-inserted")
+	private WebElement errorContainer;
+
+
+	public boolean isOKButtonPresent(){
+		return okButton.isDisplayed();
+	}
+	public boolean isCancelButtonPresent(){
+		return cancelButton.isDisplayed();
+	}
+
+	public boolean isExtensionAreaEditable(){
+		return null == extensionTextArea.getAttribute("disabled");
+	}
+	public boolean isParticipantIdentifierInputEnabled(){
+		return null == participantIdentifierInput.getAttribute("disabled");
+	}
+
+	public boolean isParticipantSchemeInputEnabled(){
+		return null == participantSchemeInput.getAttribute("disabled");
+	}
+
+	public boolean isOwnersPanelEnabled(){
+		return ownersPanel.optionsEnabled();
+	}
+
+	public boolean isOwnersPanelPresent(){
+		return null == ownersPanel;
+	}
+
+	public boolean isDomainsPanelEnabled(){
+		return domainsPanel.optionsEnabled();
+	}
+
+	public void clickOK(){
+		waitForElementToBeClickable(okButton).click();
+		waitForElementToBeGone(okButton);
+	}
+
+	public void clickCancel(){waitForElementToBeClickable(cancelButton).click();}
+
+	public void fillForm(String identifier, String scheme, List<String> owners, List<String> domains, String extension){
+		waitForElementToBeVisible(participantIdentifierInput);
+
+		clearAndFillInput(participantIdentifierInput, identifier);
+		clearAndFillInput(participantSchemeInput, scheme);
+
+		for (String owner : owners) {
+			ownersPanel.selectOptionWithText(owner);
+		}
+
+		domainsPanel.expandSection();
+
+		for (String domain : domains) {
+			domainsPanel.selectOptionWithText(domain);
+		}
+
+		clearAndFillInput(extensionTextArea, extension);
+
+	}
+
+	public String getParticipantIdentifierValue(){
+		return waitForElementToBeVisible(participantIdentifierInput).getAttribute("value").trim();
+	}
+
+	public String getParticipantSchemeValue(){
+		return participantSchemeInput.getAttribute("value").trim();
+	}
+
+	public String getErrorMessage(){
+		return errorContainer.getText().trim();
+	}
+
+	public String getExtansionAreaContent(){
+		return extensionTextArea.getAttribute("value").trim();
+	}
+
+	public void enterDataInExtensionTextArea(String text){
+		waitForElementToBeVisible(extensionTextArea).clear();
+		extensionTextArea.sendKeys(text);
+	}
+
+	public void fillParticipanIdentifier(String participantIdentifier){
+		clearAndFillInput(participantIdentifierInput, participantIdentifier);
+	}
+	public void fillParticipanScheme(String participanScheme){
+		clearAndFillInput(participantSchemeInput, participanScheme);
+	}
+	public void chooseFirstOwner(){
+		if(!ownersPanel.isExpanded()){ ownersPanel.expandSection();}
+		ownersPanel.selectOptionWithIndex(0);
+
+	}
+	public void chooseFirstDomain(){
+		if(!domainsPanel.isExpanded()){ domainsPanel.expandSection();}
+		domainsPanel.selectOptionWithIndex(0);
+	}
+	public void fillExtensionArea(String extension){
+		clearAndFillInput(extensionTextArea, extension);
+	}
+
+	public void generateRndExtension(){
+		clearAndFillInput(extensionTextArea, " ");
+		participantIdentifierInput.click();
+		extensionWizardButton.click();
+		new MetadataWizardPopup(driver).fillWithRndStrings();
+
+	}
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupRowE.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupRowE.java
new file mode 100644
index 0000000000000000000000000000000000000000..5104101b7d87c0b22df6d1b12e2006dd1549fb67
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceGroupRowE.java
@@ -0,0 +1,48 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import pages.service_groups.ServiceGroupRow;
+
+public class ServiceGroupRowE extends pages.service_groups.ServiceGroupRow {
+	public ServiceGroupRowE(WebDriver driver, WebElement container) {
+		super(driver, container);
+	}
+
+	@FindBy(css = "datatable-body-cell:nth-child(7) > div > div > button:nth-child(1)")
+	WebElement addMetadataButton;
+
+	@FindBy(css = "datatable-body-cell:nth-child(7) > div > div > button:nth-child(2)")
+	WebElement editServiceGroup;
+
+	@FindBy(css = "datatable-body-cell:nth-child(7) > div > div > button:nth-child(3)")
+	WebElement deleteServiceGroup;
+
+	@Override
+	public Integer getMetadataSize() {
+		return Integer.valueOf(cells.get(1).getText().trim());
+	}
+
+	public Integer getOwnerSize() {
+		return Integer.valueOf(cells.get(2).getText().trim());
+	}
+
+	public ServiceMetadataPopup clickAddMetadata(){
+		waitForElementToBeClickable(addMetadataButton).click();
+
+		return new ServiceMetadataPopup(driver);
+	}
+
+	public ServiceGroupPopup clickEdit(){
+		waitForElementToBeClickable(editServiceGroup).click();
+		return new ServiceGroupPopup(driver);
+	}
+
+	public void clickDelete(){
+		waitForElementToBeClickable(deleteServiceGroup).click();
+	}
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceMetadataPopup.java b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceMetadataPopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..60e77788965706bf5aacd561cce7b221cd9a5364
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/edit/ServiceMetadataPopup.java
@@ -0,0 +1,83 @@
+package pages.service_groups.edit;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.GenericSelect;
+import pages.components.baseComponents.PageComponent;
+import utils.PROPERTIES;
+
+public class ServiceMetadataPopup extends PageComponent {
+	public ServiceMetadataPopup(WebDriver driver) {
+		super(driver);
+
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+
+		domainSelect = new GenericSelect(driver, domainSelectContainer);
+	}
+
+	@FindBy(css = "mat-dialog-actions > div > button:nth-child(1)")
+	private WebElement okButton;
+
+	@FindBy(css = "mat-dialog-actions > div > button:nth-child(2)")
+	private WebElement cancelButton;
+
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(1)")
+	private WebElement clearButon;
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(2)")
+	private WebElement generateXMLButton;
+	@FindBy(css = "mat-card-content > mat-toolbar > mat-toolbar-row > button:nth-child(3)")
+	private WebElement validateButton;
+
+	@FindBy(css = "#MetadataTextArea")
+	private WebElement metadataTextArea;
+
+	@FindBy(css = "#participanSchema_id")
+	private WebElement participanSchemaInput;
+
+	@FindBy(css = "#participantIdentifier_id")
+	private WebElement participantIdentifierInput;
+
+	@FindBy(css = "#documentScheme_id")
+	private WebElement documentSchemeInput;
+
+	@FindBy(css = "#documentIdentifier_id")
+	private WebElement documentIdentifierInput;
+
+	@FindBy(css = "mat-dialog-content #domain_id")
+	private WebElement domainSelectContainer;
+	private GenericSelect domainSelect;
+
+
+	public void fillForm(String domain, String docID, String docScheme) {
+		waitForElementToBeVisible(documentIdentifierInput);
+		domainSelect.selectOptionWithText(domain);
+
+		clearAndFillInput(documentIdentifierInput, docID);
+		clearAndFillInput(documentSchemeInput, docScheme);
+
+		generateXMLButton.click();
+
+		waitForElementToBeClickable(okButton).click();
+
+	}
+
+	public String getParticipantSchemeValue(){return participanSchemaInput.getAttribute("value").trim();}
+	public String getParticipantIdentifierValue(){return participantIdentifierInput.getAttribute("value").trim();}
+	public String getDocumentIdentifierValue(){return documentIdentifierInput.getAttribute("value").trim();}
+	public String getDocumentSchemeValue(){return documentSchemeInput.getAttribute("value").trim();}
+
+	public boolean isParticipantSchemeEnabled(){return null == participanSchemaInput.getAttribute("disabled");}
+	public boolean isParticipantIdentifierEnabled(){return null == participantIdentifierInput.getAttribute("disabled");}
+	public boolean isDocumentIdentifierEnabled(){return null == documentIdentifierInput.getAttribute("disabled");}
+	public boolean isDocumentSchemeEnabled(){return null == documentSchemeInput.getAttribute("disabled");}
+
+
+
+	public String getlistedDomain(){return domainSelect.getSelectedValue().trim();}
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/search/SearchPage.java b/smp-ui-tests/src/main/java/pages/service_groups/search/SearchPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..c4c8331ece7df1e249bb2d6e6db148954a266f64
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/search/SearchPage.java
@@ -0,0 +1,34 @@
+package pages.service_groups.search;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import pages.components.baseComponents.SMPPage;
+import pages.service_groups.ServiceGroupGrid;
+import pages.service_groups.FilterArea;
+import utils.PROPERTIES;
+
+public class SearchPage extends SMPPage {
+	public SearchPage(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+
+		serviceGroupGrid = new ServiceGroupGrid(driver, searchGridContainer);
+
+	}
+
+	public FilterArea filters = new FilterArea(driver);
+
+	@FindBy(id = "searchTable")
+	WebElement searchGridContainer;
+	public ServiceGroupGrid serviceGroupGrid;
+
+
+	public boolean isLoaded() {
+		if(!filters.isLoaded()){ return false;}
+		if(!serviceGroupGrid.isLoaded()){ return false;}
+		return true;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ParticipantIdentifier.java b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ParticipantIdentifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0d3902d01a607dd1f8caa93e38264c9dad57016
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ParticipantIdentifier.java
@@ -0,0 +1,40 @@
+package pages.service_groups.search.pojo;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;
+
+@XStreamAlias("ParticipantIdentifier")
+@XStreamConverter(value= ToAttributedValueConverter.class, strings={"participantIdentifier"})
+public class ParticipantIdentifier {
+
+
+	String scheme;
+
+
+	String participantIdentifier;
+
+	public String getScheme() {
+		return scheme;
+	}
+
+	public void setScheme(String scheme) {
+		this.scheme = scheme;
+	}
+
+	public String getParticipantIdentifier() {
+		return participantIdentifier;
+	}
+
+	public void setParticipantIdentifier(String participantIdentifier) {
+		this.participantIdentifier = participantIdentifier;
+	}
+
+	@Override
+	public String toString() {
+		return "ParticipantIdentifier{" +
+				"scheme='" + scheme + '\'' +
+				", participantIdentifier='" + participantIdentifier + '\'' +
+				'}';
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceGroup.java b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e8454b44871ee9690482ddd61d116d9d824a9c2
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceGroup.java
@@ -0,0 +1,39 @@
+package pages.service_groups.search.pojo;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import java.util.List;
+
+@XStreamAlias("ServiceGroup")
+public class ServiceGroup {
+
+	@XStreamAlias("ParticipantIdentifier")
+	ParticipantIdentifier participantIdentifier;
+
+	@XStreamAlias("ServiceMetadataReferenceCollection")
+	List<ServiceMetadataReference> serviceMetadataReferenceCollection;
+
+	public ParticipantIdentifier getParticipantIdentifier() {
+		return participantIdentifier;
+	}
+
+	public void setParticipantIdentifier(ParticipantIdentifier participantIdentifier) {
+		this.participantIdentifier = participantIdentifier;
+	}
+
+	public List<ServiceMetadataReference> getServiceMetadataReferenceCollection() {
+		return serviceMetadataReferenceCollection;
+	}
+
+	public void setServiceMetadataReferenceCollection(List<ServiceMetadataReference> serviceMetadataReferenceCollection) {
+		this.serviceMetadataReferenceCollection = serviceMetadataReferenceCollection;
+	}
+
+	@Override
+	public String toString() {
+		return "ServiceGroup{" +
+				"participantIdentifier=" + participantIdentifier +
+				", serviceMetadataReferenceCollection=" + serviceMetadataReferenceCollection +
+				'}';
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceMetadataReference.java b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceMetadataReference.java
new file mode 100644
index 0000000000000000000000000000000000000000..d911c0aae9c2ad0b2220233304bb52aa9ec0fdc3
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/service_groups/search/pojo/ServiceMetadataReference.java
@@ -0,0 +1,26 @@
+package pages.service_groups.search.pojo;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
+
+@XStreamAlias("ServiceMetadataReference")
+public class ServiceMetadataReference {
+
+	@XStreamAsAttribute
+	String href;
+
+	public String getHref() {
+		return href;
+	}
+
+	public void setHref(String href) {
+		this.href = href;
+	}
+
+	@Override
+	public String toString() {
+		return "ServiceMetadataReference{" +
+				"href='" + href + '\'' +
+				'}';
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/users/UserPopup.java b/smp-ui-tests/src/main/java/pages/users/UserPopup.java
new file mode 100644
index 0000000000000000000000000000000000000000..70f772313b487bd5e168baa1a0bbc293bfd61c9a
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/users/UserPopup.java
@@ -0,0 +1,127 @@
+package pages.users;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import pages.components.GenericSelect;
+import pages.components.baseComponents.PageComponent;
+
+public class UserPopup extends PageComponent {
+	public UserPopup(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements(driver, this);
+		rolesSelect = new GenericSelect(driver, rolesSelectContainer);
+	}
+
+
+
+	
+	@FindBy(id = "userDetailsToggle_id")
+	WebElement userDetailsToggle;
+	
+	@FindBy(css = "#active_id > label > div > div")
+	WebElement activeToggle;
+
+	@FindBy(id = "username_id")
+	WebElement userNameInput;
+	
+	@FindBy(id = "emailAddress_id")
+	WebElement emailInput;
+	
+	@FindBy(id = "password_id")
+	WebElement passwordInput;
+	
+	@FindBy(id = "usernameconfirmation_id")
+	WebElement confirmationInput;
+	
+	@FindBy(css = "mat-form-field.username> div > div.mat-form-field-flex > div > div")
+	WebElement usernameValidationError;
+
+	@FindBy(css = "mat-form-field.password > div > div.mat-form-field-flex > div > div")
+	WebElement passValidationError;
+
+	@FindBy(css = "mat-form-field.password-confirmation > div > div.mat-form-field-flex > div > div")
+	WebElement passConfirmationValidationError;
+
+	@FindBy(css = "mat-dialog-content > table > tbody > tr > td > button:nth-child(1)")
+	WebElement okBtn;
+	
+	@FindBy(css = "mat-dialog-content > table > tbody > tr > td > button:nth-child(2)")
+	WebElement cancelBtn;
+	
+	@FindBy(css = "#role_id")
+	WebElement rolesSelectContainer;
+	public GenericSelect rolesSelect;
+	
+	
+
+
+	public boolean isOKButtonActive(){
+		return waitForElementToBeVisible(okBtn).isEnabled();
+	}
+	
+	public boolean isCancelButtonActive(){
+		return waitForElementToBeVisible(cancelBtn).isEnabled();
+	}
+
+	public void fillData(String user, String email, String role, String password, String confirmation){
+		clearAndFillInput(userNameInput, user);
+		clearAndFillInput(emailInput, email);
+		clearAndFillInput(passwordInput, password);
+		clearAndFillInput(confirmationInput, confirmation);
+		
+		GenericSelect rolesSelect = new GenericSelect(driver, rolesSelectContainer);
+		rolesSelect.selectOptionByText(role);
+
+	}
+	
+	public void clickOK(){
+		waitForElementToBeClickable(okBtn);
+		okBtn.click();
+		waitForElementToBeGone(okBtn);
+	}
+	
+	public void clickCancel(){
+		waitForElementToBeClickable(cancelBtn);
+		cancelBtn.click();
+		waitForElementToBeGone(cancelBtn);
+	}
+	
+	
+	public void clickUserDetailsToggle() {
+		userDetailsToggle.click();
+		waitForElementToBeEnabled(userNameInput);
+	}
+	
+	public void fillDetailsForm(String username, String pass, String confirmation) {
+		clearAndFillInput(userNameInput, username);
+		clearAndFillInput(passwordInput, pass);
+		clearAndFillInput(confirmationInput, confirmation);
+		emailInput.click();
+	}
+
+
+	public String getUsernameValidationEror(){
+		try {
+			return usernameValidationError.getText();
+		} catch (Exception e) {	}
+		return null;
+	}
+
+	public String getPassValidationEror(){
+
+		try {
+			return passValidationError.getText();
+		} catch (Exception e) {	}
+		return null;
+	}
+
+	public String getConfirmationPassValidationEror(){
+
+		try {
+			return passConfirmationValidationError.getText();
+		} catch (Exception e) {	}
+		return null;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/users/UserRowInfo.java b/smp-ui-tests/src/main/java/pages/users/UserRowInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c17dcda9a3d8504384f2af61ff3c1c33a5120d4
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/users/UserRowInfo.java
@@ -0,0 +1,38 @@
+package pages.users;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+import java.util.ArrayList;
+
+public class UserRowInfo{
+	
+	private String username;
+	private String role;
+	private String certificate;
+	
+	
+	public String getUsername() {
+		return username;
+	}
+	
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	
+	public String getRole() {
+		return role;
+	}
+	
+	public void setRole(String role) {
+		this.role = role;
+	}
+	
+	public String getCertificate() {
+		return certificate;
+	}
+	
+	public void setCertificate(String certificate) {
+		this.certificate = certificate;
+	}
+}
diff --git a/smp-ui-tests/src/main/java/pages/users/UsersGrid.java b/smp-ui-tests/src/main/java/pages/users/UsersGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..864e47863e96e6ee1f06e2d35c7763c3d56b2b93
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/users/UsersGrid.java
@@ -0,0 +1,32 @@
+package pages.users;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import pages.components.grid.BasicGrid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UsersGrid extends BasicGrid {
+	public UsersGrid(WebDriver driver, WebElement container) {
+		super(driver, container);
+	}
+	
+	public List<UserRowInfo> getRows(){
+		List<UserRowInfo> rowInfos = new ArrayList<>();
+		
+		for (WebElement gridRow : gridRows) {
+			List<WebElement> cells = gridRow.findElements(By.tagName("datatable-body-cell"));
+			UserRowInfo rowInfo = new UserRowInfo();
+			rowInfo.setUsername(cells.get(0).getText().trim());
+			rowInfo.setCertificate(cells.get(1).getText().trim());
+			rowInfo.setRole(cells.get(2).getText().trim());
+			rowInfos.add(rowInfo);
+		}
+		return rowInfos;
+	}
+	
+	
+	
+}
diff --git a/smp-ui-tests/src/main/java/pages/users/UsersPage.java b/smp-ui-tests/src/main/java/pages/users/UsersPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..f26a339a41ec3206eee14cab79d49580dc328b85
--- /dev/null
+++ b/smp-ui-tests/src/main/java/pages/users/UsersPage.java
@@ -0,0 +1,119 @@
+package pages.users;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.PaginationControls;
+import pages.components.baseComponents.SMPPage;
+import pages.components.grid.BasicGrid;
+import utils.PROPERTIES;
+
+import java.util.List;
+
+public class UsersPage extends SMPPage {
+	public UsersPage(WebDriver driver) {
+		super(driver);
+		PageFactory.initElements( new AjaxElementLocatorFactory(driver, PROPERTIES.TIMEOUT), this);
+	}
+
+
+	public PaginationControls pagination = new PaginationControls(driver);
+
+	@FindBy(id = "searchTable")
+	private WebElement userTableContainer;
+	
+	@FindBy(id = "cancelButton")
+	private WebElement cancelBtn;
+	
+	@FindBy(id = "saveButton")
+	private WebElement saveBtn;
+	
+	@FindBy(id = "newButton")
+	private WebElement newBtn;
+	
+	@FindBy(id = "editButton")
+	private WebElement editBtn;
+	
+	@FindBy(id = "deleteButton")
+	private WebElement deleteBtn;
+	
+	
+	public boolean isLoaded(){
+		
+		if(!cancelBtn.isDisplayed()){return false;}
+		if(!saveBtn.isDisplayed()){return false;}
+		if(!newBtn.isDisplayed()){return false;}
+		if(!newBtn.isEnabled()){return false;}
+		if(!editBtn.isDisplayed()){return false;}
+		if(!deleteBtn.isDisplayed()){return false;}
+		
+		return true;
+	}
+	
+	public boolean isCancelButtonEnabled(){
+		waitForElementToBeEnabled(cancelBtn);
+		return cancelBtn.isEnabled();
+	}
+	public boolean isSaveButtonEnabled(){
+		waitForElementToBeEnabled(saveBtn);
+		return saveBtn.isEnabled();
+	}
+	public boolean isDeleteButtonEnabled(){
+		waitForElementToBeEnabled(deleteBtn);
+		return deleteBtn.isEnabled();
+	}
+	public boolean isEditButtonEnabled(){
+		return editBtn.isEnabled();
+	}
+	public boolean isNewButtonEnabled(){
+		return newBtn.isEnabled();
+	}
+	
+	public ConfirmationDialog clickCancel(){
+		waitForElementToBeClickable(cancelBtn).click();
+		return new ConfirmationDialog(driver);
+	}
+	
+	public ConfirmationDialog clickSave(){
+		waitForElementToBeClickable(saveBtn).click();
+		return new ConfirmationDialog(driver);
+	}
+	
+	public void clickDelete(){
+		waitForElementToBeClickable(deleteBtn).click();
+	}
+	public UserPopup clickNew(){
+		waitForElementToBeClickable(newBtn).click();
+		return new UserPopup(driver);
+	}
+	public UserPopup clickEdit(){
+		waitForElementToBeClickable(editBtn).click();
+		return new UserPopup(driver);
+	}
+	
+	
+	public UsersGrid grid(){
+		return new UsersGrid(driver, userTableContainer);
+	}
+	
+
+
+	public void createUser(){
+		waitForElementToBeClickable(newBtn).click();
+
+		UserPopup popup = new UserPopup(driver);
+//		popup.fillData(user,"",role,password,password);
+		popup.clickOK();
+
+	}
+	
+	
+	
+	
+	
+	
+}
diff --git a/smp-ui-tests/src/main/java/utils/DriverManager.java b/smp-ui-tests/src/main/java/utils/DriverManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..6169400ffdca80d4e361e28e0e4b96db1e35fae4
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/DriverManager.java
@@ -0,0 +1,40 @@
+package utils;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.firefox.FirefoxDriverLogLevel;
+import org.openqa.selenium.firefox.FirefoxOptions;
+
+import java.util.logging.Level;
+
+public class DriverManager {
+
+//	public static WebDriver getDriver(){
+//
+//		ChromeOptions options = new ChromeOptions();
+//		options.addArguments("--headless");
+//		options.addArguments("--window-size=1920x1080");
+//		options.addArguments("--no-sandbox");
+//
+//		WebDriver driver = new ChromeDriver(options);
+//		driver.manage().window().maximize();
+//
+//		return driver;
+//    }
+
+    public static WebDriver getDriver(){
+		System.setProperty(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE,"true");
+		System.setProperty(FirefoxDriver.SystemProperty.BROWSER_LOGFILE,"C:\\temp\\logs.txt");
+
+
+
+		WebDriver driver = new FirefoxDriver();
+		driver.manage().window().maximize();
+
+		return driver;
+    }
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/Generator.java b/smp-ui-tests/src/main/java/utils/Generator.java
new file mode 100644
index 0000000000000000000000000000000000000000..96d1df15d1453bbe475fb63d8d5f6286a9586f35
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/Generator.java
@@ -0,0 +1,18 @@
+package utils;
+
+public class Generator {
+	
+	private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+	
+	
+	public static String randomAlphaNumeric(int count) {
+		StringBuilder builder = new StringBuilder();
+		while (count-- != 0) {
+			int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
+			builder.append(ALPHA_NUMERIC_STRING.charAt(character));
+		}
+		return builder.toString();
+	}
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/PROPERTIES.java b/smp-ui-tests/src/main/java/utils/PROPERTIES.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9a791cde63a892deecf6095eec32bd126f78c23
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/PROPERTIES.java
@@ -0,0 +1,12 @@
+package utils;
+
+public class PROPERTIES {
+
+	public static final String UI_BASE_URL = System.getProperty("UI_BASE_URL");
+	public static final int TIMEOUT = Integer.valueOf(System.getProperty("SHORT_TIMEOUT"));
+	public static final int LONG_WAIT = Integer.valueOf(System.getProperty("LONG_TIMEOUT"));
+	public static final String REPORTS_FOLDER = System.getProperty("reports.folder");
+	public static final String TESTDATAFILE = System.getProperty("data.folder") + System.getProperty("testdata.file");
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/TestDataProvider.java b/smp-ui-tests/src/main/java/utils/TestDataProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b567c1d8371f497efaa2bc48b0f023d9da81690
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/TestDataProvider.java
@@ -0,0 +1,59 @@
+package utils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Iterator;
+
+public class TestDataProvider {
+
+    private JSONObject testData = null;
+
+
+    public TestDataProvider(){
+
+        String content = null;
+        try {
+            content = new String(Files.readAllBytes(Paths.get(PROPERTIES.TESTDATAFILE)));
+         	testData = new JSONObject(content);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public HashMap<String, String> getUserWithRole(String key){
+        HashMap<String, String> toReturn = new HashMap<>();
+
+		try {
+			JSONObject user = null;
+			user = testData.getJSONObject("loginUsers").getJSONObject(key);
+
+			Iterator<String> keysItr = user.keys();
+			while(keysItr.hasNext()) {
+				String usrKey = keysItr.next();
+				toReturn.put(usrKey, user.getString(usrKey));
+			}
+		} catch (JSONException e) {	}
+
+		return toReturn;
+    }
+
+	public String getDefaultTestPass(){
+		try {
+			return testData.getString("passwordForTestUsers");
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+		return "";
+	}
+
+
+
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/customReporter/ExcelTestReporter.java b/smp-ui-tests/src/main/java/utils/customReporter/ExcelTestReporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..1631955e689ea8061ce2856f941366ce9271b2b7
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/customReporter/ExcelTestReporter.java
@@ -0,0 +1,188 @@
+package utils.customReporter;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFFont;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+import utils.PROPERTIES;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class ExcelTestReporter implements ITestListener {
+
+	private static final String[] headers = {"Type", "Test Suite Name", "Test Case ID", "Test Case Name", "Can be run on Bamboo", "TC is disabled", "Test Result", "Last Execution Started", "Execution time", "JIRA tickets", "Impact", "Comment"};
+	private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+	private static String filename;
+
+
+	@Override
+	/*Creates the report file, the sheet and writes the headers of the table with style as well*/
+	public void onStart(ITestContext iTestContext) {
+		
+		
+		
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm");
+		String dateStr = format.format(iTestContext.getStartDate());
+		filename = PROPERTIES.REPORTS_FOLDER + "TestRunReport" + dateStr + ".xlsx";
+
+		XSSFWorkbook workbook = new XSSFWorkbook();
+		Sheet sheet = workbook.createSheet("Run Report");
+
+		Row headerRow = sheet.createRow(0);
+		XSSFCellStyle headerStyle = composeCellStyle((XSSFWorkbook) sheet.getWorkbook(), "Header");
+
+		for (int i = 0; i < headers.length; i++) {
+			Cell cell = headerRow.createCell(i);
+			cell.setCellStyle(headerStyle);
+			cell.setCellValue(headers[i]);
+		}
+
+		try{
+			FileOutputStream os = new FileOutputStream(filename);
+			workbook.write(os);
+			workbook.close();
+			os.close();
+		} catch (Exception e){
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public void onFinish(ITestContext iTestContext) {
+
+	}
+
+	@Override
+	public void onTestStart(ITestResult iTestResult) {
+
+	}
+
+	/* Writes a row in the report file with the test id, name  and Pass as status */
+	@Override
+	public void onTestSuccess(ITestResult iTestResult) {
+		try {
+			writeRowToReportFile(iTestResult, "Pass");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/* Writes a row in the report file with the test id, name  and FAIL as status*/
+	@Override
+	public void onTestFailure(ITestResult iTestResult) {
+		try {
+			writeRowToReportFile(iTestResult, "FAIL");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/* Writes a row in the report file with the test id, name and Skipped as status */
+	@Override
+	public void onTestSkipped(ITestResult iTestResult) {
+		try {
+			writeRowToReportFile(iTestResult, "Skipped");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) {
+
+	}
+
+
+	/* depending on the type of cell returns the desired style. The supported type are "Header", "Fail", "Pass" */
+	private XSSFCellStyle composeCellStyle(XSSFWorkbook workbook, String type){
+		XSSFCellStyle style = workbook.createCellStyle();
+		XSSFFont font = workbook.createFont();
+		font.setBold(true);
+
+		if(type.equalsIgnoreCase("Pass")){
+			style.setFillBackgroundColor(IndexedColors.BRIGHT_GREEN.getIndex());
+			style.setFillForegroundColor(IndexedColors.BRIGHT_GREEN.getIndex());
+
+		}else if (type.equalsIgnoreCase("Fail")){
+			style.setFillBackgroundColor(IndexedColors.RED.getIndex());
+			style.setFillForegroundColor(IndexedColors.RED.getIndex());
+			style.setFont(font);
+
+		}else if (type.equalsIgnoreCase("Skipped")){
+			style.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
+			style.setFillForegroundColor(IndexedColors.WHITE.getIndex());
+			style.setFont(font);
+
+		}
+		else if (type.equalsIgnoreCase("Header")){
+			style.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+			style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+			style.setFont(font);
+		}
+		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+
+		return style;
+	}
+
+	/* Generic method to write a row in the report file with the test id, name and result */
+	private void writeRowToReportFile(ITestResult iTestResult, String result) throws Exception {
+
+		String qualifiedName = iTestResult.getMethod().getQualifiedName();
+		String testType = "";
+		if(qualifiedName.contains(".ui.")){testType = "UI";}
+		if(qualifiedName.contains(".rest.")){testType = "REST";}
+		
+		File myFile = new File(filename);
+		FileInputStream inputStream = new FileInputStream(myFile);
+		XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
+
+		Sheet reportSheet = workbook.getSheetAt(0);
+		int rowNum = reportSheet.getLastRowNum()+1;
+		Row curentRow = reportSheet.createRow(rowNum);
+
+		curentRow.createCell(0).setCellValue(testType);
+//		curentRow.createCell(0).setCellValue("UI");
+		curentRow.createCell(1).setCellValue(iTestResult.getTestContext().getSuite().getName());
+		curentRow.createCell(2).setCellValue(iTestResult.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description());
+		curentRow.createCell(3).setCellValue(iTestResult.getName());
+		curentRow.createCell(4).setCellValue("Yes");
+		curentRow.createCell(5).setCellValue(!iTestResult.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).enabled());
+		Cell cell = curentRow.createCell(6);
+		cell.setCellValue(result);
+		cell.setCellStyle(composeCellStyle(workbook, result));
+		curentRow.createCell(7).setCellValue(sdf.format(new Date(iTestResult.getStartMillis())));
+		curentRow.createCell(8).setCellValue((iTestResult.getEndMillis()-iTestResult.getStartMillis())/1000);
+		curentRow.createCell(9).setCellValue("");
+		curentRow.createCell(10).setCellValue("");
+
+		if(iTestResult.getThrowable() != null){
+			curentRow.createCell(11).setCellValue(iTestResult.getThrowable().getMessage());
+		}
+
+
+		FileOutputStream os = new FileOutputStream(myFile);
+		workbook.write(os);
+		os.close();
+		workbook.close();
+		inputStream.close();
+
+	}
+
+
+
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/enums/SMPMessages.java b/smp-ui-tests/src/main/java/utils/enums/SMPMessages.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fcf898fb2b698b4d49719a4b6a8efc6e51c9455
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/enums/SMPMessages.java
@@ -0,0 +1,82 @@
+package utils.enums;
+
+public class SMPMessages {
+
+	public static final String MSG_1 = "The username/password combination you provided are not valid. Please try again or contact your administrator.";
+	public static final String MSG_2 = "Too many invalid attempts to log in. Access has been temporarily\n" +
+										"suspended. Please try again later with the right credentials.";
+	public static final String MSG_3 = "To abandon all changes performed since last save, click on the \"Cancel\" button.\n" +
+										"Click on the \"Ok\" button keep your changes and come back to the current\n" +
+										"window unchanged.";
+	public static final String MSG_4 = "Please confirm by clicking on the \"Save\" button that you want to save all changes.\n" +
+										"If you don't want to save these changes now, please click on the \"Don't\n" +
+										"save now\" button";
+	public static final String MSG_5 = "To delete the current item(s) click on the \"Ok\" button.\n" +
+										"Click on the \"Cancel\" button to keep this item and come back to the\n" +
+										"current window unchanged";
+	public static final String MSG_6 = "The system detected a concurrent access.\n" +
+										"Your changes are irremediably lost, and the data were reverted to what\n" +
+										"the concurrent user saved before you.";
+	public static final String MSG_7 = "Component ${COMPONENT} is not accessible. Administration console is\n" +
+										"disabled.";
+	public static final String MSG_8 = "You are about to leave the edition of the current ${OBJECT_TYPE} which\n" +
+										"modifications were not saved yet.\n" +
+										"Click on \"Abandon\" to abandon your changes.\n" +
+										"Click \"Keep\" to stay on the current screen and keep your changes without\n" +
+										"saving them now"+
+										"Click \"Save\" to save your changes and move to the selected screen.";
+	public static final String MSG_9 = "The selection criteria you provided are too restrictive, no result matches\n" +
+										"these criteria. Please enter less selective criteria to obtain some results";
+	public static final String MSG_10 = "A value must be provided for the plugin and at least for one of the other\n" +
+										"column for the filter to be applicable.";
+	public static final String MSG_11 = "You are about to delete ServiceGroup: ${ServiceGroup} and its ServiceMetadata.\n" +
+										"Click on \"Delete\" to confirm the deletion.\n" +
+										"Click on \"Keep\" to keep the ServiceMetadata.";
+	public static final String MSG_12 = "You are about to delete ServiceMetadata: ${ServiceMetadata}.\n" +
+										"Click on \"Delete\" to confirm the deletion.\n" +
+										"Click on \"Keep\" to keep the ServiceMetadata";
+	public static final String MSG_13 = "You are about to delete User: ${User}.\n" +
+										"Click on \"Delete\" to confirm the deletion.\n" +
+										"Click on \"Keep\" to keep the user.\n";
+	public static final String MSG_14 = "You are about to create an SMP Domain: ${SMP_BDMSL_ID}. Action will\n" +
+										"register new user SMP user to SML for domain ${ BDMSL _DOMAIN}.\n" +
+										"Domain will be saved to SMP. Action is not recoverable.\n" +
+										"Click on \"Register\" to confirm the registration and saving.\n" +
+										"Click on \"Cancel\" to cancel the registration.";
+	public static final String MSG_15 = "You are about to delete an SMP Domain: ${SMP_DOMAIN_ID}. Action\n" +
+										"will unregister SMP domain user ${SMP_SML_ID}. from SML for domain\n" +
+										"${ BDMSL _DOMAIN}. Action is not recoverable.\n" +
+										"Click on \"Delete\" to confirm the deleting and unregistration of domain.\n" +
+										"Click on \"Keep\" to keep the domain.";
+	public static final String MSG_16 = "You are about to delete an X509 private key: ${Key }. Action is not recoverable.\n" +
+										"Click on \"Delete\" to confirm the deleting the key.\n" +
+										"Click on \"Keep\" to keep the key.";
+	public static final String MSG_17 = "You are about to delete Domain: ${SMP_DOMAIN_ID}.\n" +
+										"Click on \"Delete\" to confirm the deletion.\n" +
+										"Click on \"Keep\" to keep the domain.";
+	public static final String MSG_18 = "The operation 'update' completed successfully.";
+
+	public static final String USER_OWN_DELETE_ERR = "Delete validation error Could not delete logged user!";
+
+	public static final String MSG_19 = "Domain ${BDMSL_DOMAIN} is already registered with id ${DOMAIN_ID}";
+	public static final String MSG_20 = "All changes were aborted and data restored into the present window";
+	public static final String MSG_21 = "Unable to login. SMP is not running.";
+
+
+	public static final String USERNAME_VALIDATION_MESSAGE = "Username can only contain alphanumeric characters (letters A-Z, numbers 0-9) and must have from 4 to 32 characters!";
+	public static final String PASS_POLICY_MESSAGE = "Password should follow all of these rules:\n" +
+			"- Minimum length: 8 characters\n" +
+			"- Maximum length: 32 characters\n" +
+			"- At least one letter in lowercase\n" +
+			"- At least one letter in uppercase\n" +
+			"- At least one digit\n" +
+			"- At least one special character";
+	public static final String PASS_NO_MATCH_MESSAGE = "Passwords do not match";
+	public static final String PASS_NO_EMPTY_MESSAGE = "You should type a password";
+
+	
+
+
+
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/rest/SMPPaths.java b/smp-ui-tests/src/main/java/utils/rest/SMPPaths.java
new file mode 100644
index 0000000000000000000000000000000000000000..067864a6771e1417f907a3d1ef8cc6ae601da4b0
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/rest/SMPPaths.java
@@ -0,0 +1,13 @@
+package utils.rest;
+
+import utils.PROPERTIES;
+
+public class SMPPaths {
+
+	public static final String REST_DOMAIN_LIST = "rest/domain";
+	public static final String REST_POST_DOMAIN = "rest/domain";
+	public static final String LOGIN_PATH = "rest/security/authentication";
+	public static final String USER_LIST = "rest/user";
+	public static final String SERVICE_GROUP = "rest/servicegroup";
+
+}
diff --git a/smp-ui-tests/src/main/java/utils/rest/SMPRestClient.java b/smp-ui-tests/src/main/java/utils/rest/SMPRestClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..44433e9693e565a1214e0699acc2930378ca5a98
--- /dev/null
+++ b/smp-ui-tests/src/main/java/utils/rest/SMPRestClient.java
@@ -0,0 +1,277 @@
+package utils.rest;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.StaxDriver;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import pages.service_groups.search.pojo.ServiceGroup;
+import utils.PROPERTIES;
+import utils.TestDataProvider;
+
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class SMPRestClient {
+
+	private static Client client = Client.create();
+	private static WebResource resource = client.resource(PROPERTIES.UI_BASE_URL);
+
+	public static ServiceGroup getServiceGroup(String url){
+//		downloading XML and parsing
+		XStream xstream = new XStream(new StaxDriver());
+		xstream.ignoreUnknownElements();
+		xstream.processAnnotations(ServiceGroup.class);
+		ServiceGroup serviceGroup = null;
+		try {
+			String tmp = client.resource(url).get(String.class);
+			serviceGroup = (ServiceGroup) xstream.fromXML(tmp);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return serviceGroup;
+	}
+
+
+	public static List<String> getDomainAndSubdomain(){
+		List<String> domainList = new ArrayList<>();
+		try {
+			String responseRaw = resource.path(SMPPaths.REST_DOMAIN_LIST)
+					.queryParam("page", "-1")
+					.queryParam("pageSize", "-1")
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.get(String.class);
+			JSONArray restDomains = new JSONObject(responseRaw).getJSONArray("serviceEntities");
+
+			for (int i = 0; i < restDomains.length(); i++) {
+				JSONObject currentDomain = restDomains.getJSONObject(i);
+				String currentDomainStr = currentDomain.getString("domainCode").trim();
+				String currentSubdomainStr = "" + currentDomain.getString("smlSubdomain").trim().replaceAll("null", "");
+
+				String tmp = String.format("%s (%s)", currentDomainStr, currentSubdomainStr);
+
+				domainList.add(tmp);
+			}
+		} catch (Exception e) { }
+		return domainList;
+	}
+
+	public static List<String> getDomainCodes(){
+
+		List<String> domainList = new ArrayList<>();
+		try {
+			String responseRaw = resource.path(SMPPaths.REST_DOMAIN_LIST)
+					.queryParam("page", "-1")
+					.queryParam("pageSize", "-1")
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.get(String.class);
+			JSONArray restDomains = new JSONObject(responseRaw).getJSONArray("serviceEntities");
+
+			for (int i = 0; i < restDomains.length(); i++) {
+				JSONObject currentDomain = restDomains.getJSONObject(i);
+				String currentDomainStr = currentDomain.getString("domainCode").trim();
+				domainList.add(currentDomainStr);
+			}
+		} catch (Exception e) { }
+		return domainList;
+	}
+
+	public static Cookie login(String role){
+		String authTemplate = "{\"username\": \"%s\", \"password\": \"%s\"}";
+		TestDataProvider tdp = new TestDataProvider();
+		Map<String, String> user = tdp.getUserWithRole(role);
+		String auth = String.format(authTemplate, user.get("username"), user.get("password"));
+
+		Cookie session = resource.path(SMPPaths.LOGIN_PATH).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON_TYPE)
+				.post(ClientResponse.class, auth).getCookies().get(0);
+		return session;
+	}
+
+	public static List<String> getSysAdmins(){
+		Cookie jssesionID = login("SYS_ADMIN");
+
+		try {
+			String responseRaw = resource.path(SMPPaths.USER_LIST)
+					.queryParam("page", "-1")
+					.queryParam("pageSize", "-1")
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.get(String.class);
+			JSONArray users = new JSONObject(responseRaw).getJSONArray("serviceEntities");
+
+			List<String> sysadmins = new ArrayList<>();
+
+			for (int i = 0; i < users.length(); i++) {
+				JSONObject usr = users.getJSONObject(i);
+				if(usr.getString("role").equalsIgnoreCase("SYSTEM_ADMIN")){
+					sysadmins.add(usr.getString("username"));
+				}
+			}
+			return sysadmins;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	public static boolean createDomain(String domainCode){
+		Cookie jssesionID = login("SYS_ADMIN");
+		String template = "[{\"domainCode\":\"%s\",\"smlSubdomain\":\"%s\",\"smlSmpId\":\"%s\",\"smlClientKeyAlias\":\"%s\",\"signatureKeyAlias\":\"%s\",\"status\":2,\"smlClientCertHeader\":\"%s\"}]";
+		String domainPostStr = String.format(template, domainCode, domainCode, domainCode, domainCode, domainCode, domainCode);
+
+		try {
+
+			ClientResponse getResponse = resource.path(SMPPaths.REST_POST_DOMAIN)
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.put(ClientResponse.class, domainPostStr);
+
+			return getResponse.getStatus() == 200;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+
+	public static boolean createUser(String username, String role){
+		Cookie jssesionID = login("SYS_ADMIN");
+		String template = "[{\"active\":true,\"username\":\"%s\",\"emailAddress\":\"\",\"password\":\"QW!@qw12\",\"confirmation\":\"\",\"role\":\"%s\",\"status\":2,\"statusPassword\":2,\"certificate\":{\"subject\":\"\",\"validFrom\":null,\"validTo\":null,\"issuer\":\"\",\"serialNumber\":\"\",\"certificateId\":\"\",\"fingerprints\":\"\"}}]";
+		String postStr = String.format(template, username, role);
+
+		try {
+			ClientResponse getResponse = resource.path(SMPPaths.USER_LIST)
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.put(ClientResponse.class, postStr);
+
+			return getResponse.getStatus() == 200;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+
+	public static boolean createServiceGroup(String pi, String ps, List<String> usernames, List<String> domainCodes){
+		String template = "[{\"id\":null,\"participantIdentifier\":\"%s\",\"participantScheme\":\"%s\",\"serviceMetadata\":[],\"users\":%s,\"serviceGroupDomains\":%s,\"extension\":\"\",\"status\":2}]";
+		try {
+
+			JSONArray users = new JSONArray();
+			for (String username : usernames) {
+				users.put(transformUserForSGPost(getUserForName(username)));
+			}
+
+			JSONArray domains = new JSONArray();
+			for (String codes : domainCodes) {
+				domains.put(transformDomainForSGPost(getDomainForName(codes)));
+			}
+
+			String postStr = String.format(template, pi, ps, users.toString(), domains.toString());
+
+			Cookie jssesionID = login("SMP_ADMIN");
+			ClientResponse getResponse = resource.path(SMPPaths.SERVICE_GROUP)
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.put(ClientResponse.class, postStr);
+
+			return getResponse.getStatus() == 200;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+
+	public static String getMetadataString(String url){
+		try {
+			return client.resource(url).accept(MediaType.APPLICATION_XML).get(String.class);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return "";
+	}
+
+	private static JSONObject getUserForName(String username){
+		Cookie jssesionID = login("SYS_ADMIN");
+
+		try {
+			String responseRaw = resource.path(SMPPaths.USER_LIST)
+					.queryParam("page", "-1")
+					.queryParam("pageSize", "-1")
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.get(String.class);
+			JSONArray users = new JSONObject(responseRaw).getJSONArray("serviceEntities");
+
+			for (int i = 0; i < users.length(); i++) {
+				JSONObject usr = users.getJSONObject(i);
+				if(username.equalsIgnoreCase(usr.getString("username"))){
+					return usr;
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private static JSONObject getDomainForName(String domainName){
+		Cookie jssesionID = login("SYS_ADMIN");
+		try {
+			String responseRaw = resource.path(SMPPaths.REST_DOMAIN_LIST)
+					.queryParam("page", "-1")
+					.queryParam("pageSize", "-1")
+					.accept(MediaType.APPLICATION_JSON_TYPE)
+					.type(MediaType.APPLICATION_JSON_TYPE)
+					.cookie(jssesionID)
+					.get(String.class);
+			JSONArray domains = new JSONObject(responseRaw).getJSONArray("serviceEntities");
+			for (int i = 0; i < domains.length(); i++) {
+				JSONObject dom = domains.getJSONObject(i);
+				if(domainName.equalsIgnoreCase(dom.getString("domainCode"))){
+					return dom;
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();		}
+		return null;
+	}
+
+	private static JSONObject transformUserForSGPost(JSONObject user){
+		try {
+			String template = "{\"index\":%s,\"username\":\"%s\",\"role\":\"%s\",\"id\":%s,\"status\":0,\"password\":null,\"emailAddress\":null,\"authorities\":null,\"passwordChanged\":null,\"active\":true,\"certificate\":null,\"statusPassword\":0}";
+			String index = user.getString("index");
+			String username = user.getString("username");
+			String role = user.getString("role");
+			String id = user.getString("id");
+			return new JSONObject(String.format(template, index, username, role, id));
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private static JSONObject transformDomainForSGPost(JSONObject domain){
+		try {
+			String template = "{\"domainId\":%s,\"domainCode\":\"%s\",\"smlSubdomain\":\"%s\",\"id\":null,\"smlRegistered\":false,\"serviceMetadataCount\":0,\"status\":2}";
+			String domainId = domain.getString("id");
+			String domainCode = domain.getString("domainCode");
+			String smlSubdomain = domain.getString("smlSubdomain");
+			return new JSONObject(String.format(template, domainId, domainCode, smlSubdomain));
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
diff --git a/smp-ui-tests/src/main/resources/log4j.properties b/smp-ui-tests/src/main/resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2498cfec2b33432b20707943fca37a3c16a15052
--- /dev/null
+++ b/smp-ui-tests/src/main/resources/log4j.properties
@@ -0,0 +1,9 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%d   %-5p %c - %m%n
\ No newline at end of file
diff --git a/smp-ui-tests/src/main/resources/testData.json b/smp-ui-tests/src/main/resources/testData.json
new file mode 100644
index 0000000000000000000000000000000000000000..3598128f7f311b13ad8a32b85fb56ff6271c1d7c
--- /dev/null
+++ b/smp-ui-tests/src/main/resources/testData.json
@@ -0,0 +1,7 @@
+{
+  "loginUsers" : {
+	"SYS_ADMIN" : {"username": "system", "password":"123456"},
+	"SMP_ADMIN" : {"username": "smp", "password":"123456"},
+	"SG_ADMIN" : {"username": "user", "password":"123456"}
+  }
+}
\ No newline at end of file
diff --git a/smp-ui-tests/src/test/java/ui/BaseTest.java b/smp-ui-tests/src/test/java/ui/BaseTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfdcf1e57309f20cd4f0ad87ce4f76cb484e0513
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/BaseTest.java
@@ -0,0 +1,57 @@
+package ui;
+
+import org.apache.log4j.Logger;
+import org.openqa.selenium.WebDriver;
+import org.testng.annotations.*;
+import pages.components.baseComponents.SMPPage;
+import utils.DriverManager;
+import utils.PROPERTIES;
+import utils.TestDataProvider;
+import utils.customReporter.ExcelTestReporter;
+
+import java.util.HashMap;
+
+@Listeners(ExcelTestReporter.class)
+public class BaseTest {
+
+	static WebDriver driver;
+	protected Logger logger = Logger.getLogger(this.getClass());
+	static TestDataProvider testDataProvider = new TestDataProvider();
+
+	@BeforeSuite(alwaysRun = true)
+	/*Starts the browser and navigates to the homepage. This happens once before the test
+	suite and the browser window is reused for all tests in suite*/
+	public void beforeSuite(){
+		logger.info("Starting this puppy!!!!");
+		driver = DriverManager.getDriver();
+		driver.get(PROPERTIES.UI_BASE_URL);
+	}
+
+
+	@AfterSuite(alwaysRun = true)
+	/*After the test suite is done we close the browser*/
+	public void afterSuite(){
+		logger.info("Quitting!!!! Buh bye!!!");
+		try {
+			driver.quit();
+		} catch (Exception e) {
+			logger.warn("Closing the driver failed !!!!");
+			e.printStackTrace();
+		}
+	}
+
+	@AfterClass(alwaysRun = true)
+	public void logoutAndReset(){
+		driver.get(PROPERTIES.UI_BASE_URL);
+		SMPPage page = new SMPPage(driver);
+		page.refreshPage();
+
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+	}
+	
+
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/DomainPgTest.java b/smp-ui-tests/src/test/java/ui/DomainPgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4e1b379666ce409bb8b984b08c0de371ba70765
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/DomainPgTest.java
@@ -0,0 +1,331 @@
+package ui;
+
+import org.openqa.selenium.WebDriver;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.SMPPage;
+import pages.components.messageArea.AlertMessage;
+import pages.domain.DomainGrid;
+import pages.domain.DomainPage;
+import pages.domain.DomainPopup;
+import pages.domain.DomainRow;
+import pages.users.UsersPage;
+import utils.Generator;
+import utils.enums.SMPMessages;
+import utils.rest.SMPRestClient;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DomainPgTest extends BaseTest {
+	
+	@AfterMethod
+	public void logoutAndReset(){
+		SMPPage page = new SMPPage(driver);
+		page.refreshPage();
+		
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+	}
+	
+	
+	@BeforeMethod
+	public void loginAndGoToUsersPage(){
+		
+		SMPPage page = new SMPPage(driver);
+		
+		if(!page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Login!!");
+			page.pageHeader.goToLogin().login("SYS_ADMIN");
+		}
+		
+		logger.info("Going to Domain page");
+		page.sidebar.goToPage(DomainPage.class);
+	}
+	
+	@Test(description = "DMN-0")
+	public void openDomainPage(){
+		SoftAssert soft = new SoftAssert();
+		DomainPage page = new DomainPage(driver);
+		
+		soft.assertTrue(page.isLoaded(), "Check that the page is loaded");
+		DomainGrid grid = page.grid();
+		DomainRow row0 = grid.getRowsInfo().get(0);
+		grid.doubleClickRow(0);
+		
+		DomainPopup popup = new DomainPopup(driver);
+
+		page.screenshotPage();
+		soft.assertTrue(popup.isLoaded(), "Domain popup is loaded");
+
+		soft.assertTrue(!popup.isDomainCodeInputEnabled(), "On double click Domain Code input is disabled");
+		soft.assertTrue(!popup.isSMLDomainInputEnabled(), "On double click SML Domain input is disabled");
+
+		popup.clickCancel();
+		
+		soft.assertEquals(row0, page.grid().getRowsInfo().get(0), "Row is unchanged");
+		soft.assertTrue(!page.isSaveButtonEnabled(), "Save button is not enabled");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "DMN-10")
+	public void editDomain(){
+		SoftAssert soft = new SoftAssert();
+		DomainPage page = new DomainPage(driver);
+
+		soft.assertTrue(page.isLoaded(), "Check that the page is loaded");
+		DomainGrid grid = page.grid();
+		DomainRow row0 = grid.getRowsInfo().get(0);
+		grid.doubleClickRow(0);
+
+		DomainPopup popup = new DomainPopup(driver);
+
+		soft.assertTrue(popup.isLoaded(), "Domain popup is loaded");
+
+		soft.assertTrue(!popup.isDomainCodeInputEnabled(), "On double click Domain Code input is disabled");
+		soft.assertTrue(!popup.isSMLDomainInputEnabled(), "On double click SML Domain input is disabled");
+
+		String rndString = Generator.randomAlphaNumeric(10);
+		popup.fillSMLSMPIdInput(rndString);
+		popup.clickCancel();
+
+		soft.assertEquals(row0, page.grid().getRowsInfo().get(0), "Row 0 is not changed");
+
+		page.grid().doubleClickRow(0);
+		popup = new DomainPopup(driver);
+		popup.fillSMLSMPIdInput(rndString);
+		popup.clickOK();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled");
+		soft.assertNotEquals(row0, page.grid().getRowsInfo().get(0), "Row 0 is changed");
+
+		page.clickSave().confirm();
+
+		DomainRow newRow0 = page.grid().getRowsInfo().get(0);
+		soft.assertNotEquals(row0, newRow0, "Row 0 is changed after save");
+		soft.assertEquals(newRow0.getSmlSmpID(), rndString, "SML SMP ID is changed to the desired string");
+
+		soft.assertEquals(page.alertArea.getAlertMessage().getMessage(), SMPMessages.MSG_18, "Proper message displayed");
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "DMN-20")
+	public void newDomain(){
+		SoftAssert soft = new SoftAssert();
+		DomainPage page = new DomainPage(driver);
+
+		soft.assertTrue(page.isLoaded(), "Check that the page is loaded");
+
+		DomainPopup popup = page.clickNew();
+		soft.assertTrue(popup.isLoaded(), "Domain popup is loaded");
+
+		soft.assertTrue(popup.isDomainCodeInputEnabled(), "When defining new domain - Domain Code input is disabled");
+		soft.assertTrue(popup.isSMLDomainInputEnabled(), "When defining new domain -SML Domain input is disabled");
+
+		String rndString = Generator.randomAlphaNumeric(10);
+
+
+		popup.fillDataForNewDomain(rndString, rndString, rndString, rndString,rndString, rndString);
+		popup.clickCancel();
+
+		soft.assertTrue(!page.isSaveButtonEnabled(), "Save button is NOT enabled");
+
+		popup = page.clickNew();
+		popup.fillDataForNewDomain(rndString, rndString, rndString, rndString,rndString, rndString);
+		popup.clickOK();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled");
+
+		page.clickSave().confirm();
+
+		soft.assertTrue(page.alertArea.getAlertMessage().getMessage().equalsIgnoreCase(SMPMessages.MSG_18),
+				"Success message is as expected");
+
+		List<DomainRow> rows = page.grid().getRowsInfo();
+		while (page.pagination.hasNextPage()){
+			page.pagination.goToNextPage();
+			rows.addAll(page.grid().getRowsInfo());
+		}
+
+		boolean found = false;
+		for (DomainRow row : rows) {
+			if(row.getDomainCode().equalsIgnoreCase(rndString)){
+				found = true;
+				break;
+			}
+		}
+
+		soft.assertTrue(found, "Found new domain in the list of domains");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "DMN-30")
+	public void cancelNewDomainCreation(){
+		SoftAssert soft = new SoftAssert();
+		DomainPage page = new DomainPage(driver);
+
+		soft.assertTrue(page.isLoaded(), "Check that the page is loaded");
+
+		DomainPopup popup = page.clickNew();
+		soft.assertTrue(popup.isLoaded(), "Domain popup is loaded");
+
+		soft.assertTrue(popup.isDomainCodeInputEnabled(), "When defining new domain - Domain Code input is disabled");
+		soft.assertTrue(popup.isSMLDomainInputEnabled(), "When defining new domain -SML Domain input is disabled");
+
+		String rndString = Generator.randomAlphaNumeric(10);
+
+
+		popup.fillDataForNewDomain(rndString, rndString, rndString, rndString,rndString, rndString);
+		popup.clickOK();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+
+		List<DomainRow> rows = page.grid().getRowsInfo();
+		while (page.pagination.hasNextPage()){
+			page.pagination.goToNextPage();
+			rows.addAll(page.grid().getRowsInfo());
+		}
+
+		boolean found = false;
+		for (DomainRow row : rows) {
+			if(row.getDomainCode().equalsIgnoreCase(rndString)){
+				found = true;
+				break;
+			}
+		}
+
+		soft.assertTrue(!found, "New domain NOT in the list of domains");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "DMN-40")
+	public void deleteDomain(){
+		String rndStr = Generator.randomAlphaNumeric(10);
+		SMPRestClient.createDomain(rndStr);
+
+		SoftAssert soft = new SoftAssert();
+		DomainPage page = new DomainPage(driver);
+
+		soft.assertTrue(page.isLoaded(), "Check that the page is loaded");
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled");
+
+		int index = scrollToDomain(rndStr);
+		page.grid().selectRow(index);
+
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row selected");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled (2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+
+		soft.assertTrue(isDomainStillPresent(rndStr), "Row is still present");
+
+		index = scrollToDomain(rndStr);
+		page.grid().selectRow(index);
+		page.clickDelete();
+		page.clickSave().confirm();
+
+		soft.assertTrue(!isDomainStillPresent(rndStr), "Row is still NOT present after delete");
+
+
+		soft.assertAll();
+	}
+
+	@Test(description = "DMN-50")
+	public void deleteDomainWithSG(){
+
+		String domainName = Generator.randomAlphaNumeric(10);
+		String pi = Generator.randomAlphaNumeric(10);
+		String ps = Generator.randomAlphaNumeric(10);
+
+		String expectedErrorMess = String.format("Delete validation error Could not delete domains used by Service groups! Domain: %s (%s ) uses by:1 SG.", domainName, domainName);
+
+		SMPRestClient.createDomain(domainName);
+		SMPRestClient.createServiceGroup(pi, ps, new ArrayList<>(Arrays.asList("smp")),new ArrayList<>(Arrays.asList(domainName)));
+
+		SoftAssert soft = new SoftAssert();
+
+		DomainPage page = new DomainPage(driver);
+
+		int index = scrollToDomain(domainName);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		AlertMessage message = page.alertArea.getAlertMessage();
+		soft.assertTrue(message.isError(), "Page shows error message when deleting domain with SG");
+		soft.assertTrue(message.getMessage().equalsIgnoreCase(expectedErrorMess), "Desired message appears");
+
+		soft.assertAll();
+	}
+
+
+
+
+	private boolean isDomainStillPresent(String domainCode){
+		boolean end = false;
+		List<DomainRow> rows = new ArrayList<>();
+		DomainPage page = new DomainPage(driver);
+		page.pagination.skipToFirstPage();
+
+		while (!end) {
+			page = new DomainPage(driver);
+			rows.addAll(page.grid().getRowsInfo());
+			if(page.pagination.hasNextPage()){
+				page.pagination.goToNextPage();
+			}else{end = true;}
+		}
+
+		boolean found = false;
+		for (DomainRow row : rows) {
+			if(row.getDomainCode().equalsIgnoreCase(domainCode)){
+				found = true;
+			}
+		}
+		return found;
+	}
+
+	private int scrollToDomain(String domainCode){
+		DomainPage page = new DomainPage(driver);
+		page.pagination.skipToFirstPage();
+
+		boolean end = false;
+		while (!end) {
+			page = new DomainPage(driver);
+
+			List<DomainRow> rows = page.grid().getRowsInfo();
+			for (int i = 0; i < rows.size(); i++) {
+				if(rows.get(i).getDomainCode().equalsIgnoreCase(domainCode)){
+					return i;
+				}
+			}
+
+			if(page.pagination.hasNextPage()){
+				page.pagination.goToNextPage();
+			}else{end = true;}
+		}
+
+		return -1;
+	}
+
+
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/EditPgTest.java b/smp-ui-tests/src/test/java/ui/EditPgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce28e98ef3e9206bc94045b1b6d67d87e70c4cf7
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/EditPgTest.java
@@ -0,0 +1,380 @@
+package ui;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.SMPPage;
+import pages.service_groups.ServiceGroupGrid;
+import pages.service_groups.edit.EditPage;
+import pages.service_groups.edit.ServiceGroupPopup;
+import pages.service_groups.edit.ServiceGroupRowE;
+import pages.service_groups.edit.ServiceMetadataPopup;
+import utils.Generator;
+import utils.rest.SMPRestClient;
+
+import java.util.List;
+
+public class EditPgTest extends BaseTest{
+
+	@AfterMethod
+	public void logoutAndReset(){
+		SMPPage page = new SMPPage(driver);
+		page.refreshPage();
+
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+		page.waitForXMillis(100);
+	}
+
+
+	@BeforeMethod
+	public void loginAndGoToEditPage(){
+
+		SMPPage page = new SMPPage(driver);
+
+		if(!page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Login!!");
+			page.pageHeader.goToLogin().login("SMP_ADMIN");
+		}
+
+		logger.info("Going to Edit page");
+		page.sidebar.goToPage(EditPage.class);
+	}
+
+
+	@Test(description = "EDT-10")
+	public void testFilters(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupRowE row0 = page.getGrid().getRowsAs(ServiceGroupRowE.class).get(0);
+		String pi = row0.getParticipantIdentifier();
+		String ps = row0.getParticipantScheme();
+
+		page.filterArea.filter(pi, ps, "");
+
+		List<ServiceGroupRowE> results = page.getGrid().getRowsAs(ServiceGroupRowE.class);
+		for (ServiceGroupRowE result : results) {
+			soft.assertTrue(result.getParticipantIdentifier().contains(pi), "Row matches searched participant identifier");
+			soft.assertTrue(result.getParticipantScheme().contains(ps), "Row matches searched participant scheme");
+		}
+
+		page.filterArea.filter(pi.substring(2), ps.substring(2), "");
+
+		results = page.getGrid().getRowsAs(ServiceGroupRowE.class);
+		for (ServiceGroupRowE result : results) {
+			soft.assertTrue(result.getParticipantIdentifier().contains(pi.substring(2)), "Row matches searched participant identifier stub");
+			soft.assertTrue(result.getParticipantScheme().contains(ps.substring(2)), "Row matches searched participant scheme stub");
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "EDT-20")
+	public void doubleclickRow(){
+		String extensionData = "<Extension xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ExtensionID>df</ExtensionID><ExtensionName>sdxf</ExtensionName><!-- Custom element is mandatory by OASIS SMP schema. Replace following element with your XML structure. --><ext:example xmlns:ext=\"http://my.namespace.eu\">my mandatory content</ext:example></Extension>";
+
+
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+		grid.doubleClickRow(index);
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+
+		soft.assertTrue(row0.getParticipantIdentifier().equalsIgnoreCase(popup.getParticipantIdentifierValue()), "Popup opened for apropriate service group");
+		soft.assertTrue(popup.isExtensionAreaEditable(), "extension area is editable");
+
+		popup.enterDataInExtensionTextArea("kjsfdfjfhskdjfhkjdhfksdjhfjksdhfjksd");
+		popup.clickOK();
+		soft.assertTrue(!popup.getErrorMessage().isEmpty(), "When entering wrong data you get an error message on save");
+
+		popup.enterDataInExtensionTextArea(extensionData);
+		popup.clickOK();
+
+		page.saveChanges();
+
+		page.getGrid().doubleClickRow(index);
+		ServiceGroupPopup popup2 = new ServiceGroupPopup(driver);
+		soft.assertEquals(popup2.getExtansionAreaContent(), extensionData, "Extension data is saved properly");
+
+		popup2.enterDataInExtensionTextArea("");
+		popup2.clickCancel();
+//TODO: refactor this assert bellow
+//		page.getGrid().doubleClickRow(0);
+//		ServiceGroupPopup popup3 = new ServiceGroupPopup(driver);
+//		soft.assertTrue(!popup3.getExtansionAreaContent().isEmpty(), "Extension data is NOT saved empty as expected");
+
+
+		soft.assertAll();
+	}
+
+	@Test(description = "EDT-30")
+	public void editActionButtonOnRow(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+
+		ServiceGroupPopup popup = row0.clickEdit();
+
+		soft.assertTrue(row0.getParticipantIdentifier().equalsIgnoreCase(popup.getParticipantIdentifierValue()), "Popup opened for apropriate service group");
+		soft.assertTrue(popup.isExtensionAreaEditable(), "extension area is editable");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "EDT-40")
+	public void editButtonOnPage(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+
+		soft.assertTrue(!page.isEditButtonEnabled(), "Edit button is not enabled before row is selected");
+
+		grid.selectRow(index);
+
+		soft.assertTrue(page.isEditButtonEnabled(), "Edit button is active after ro is selected");
+
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+
+		ServiceGroupPopup popup = page.clickEdit();
+
+		soft.assertTrue(row0.getParticipantIdentifier().equalsIgnoreCase(popup.getParticipantIdentifierValue()), "Popup opened for apropriate service group");
+		soft.assertTrue(popup.isExtensionAreaEditable(), "extension area is editable");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "EDT-50")
+	public void serviceGroupPopupUICheck(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+		grid.doubleClickRow(index);
+
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+
+		soft.assertTrue(row0.getParticipantIdentifier().equalsIgnoreCase(popup.getParticipantIdentifierValue()), "Popup opened for apropriate service group");
+		soft.assertTrue(popup.isExtensionAreaEditable(), "extension area is editable");
+
+		soft.assertTrue(!popup.isParticipantIdentifierInputEnabled(), "Participant Identifier field is disabled");
+		soft.assertTrue(!popup.isParticipantSchemeInputEnabled(), "Participant Scheme field is disabled");
+		soft.assertTrue(popup.isOwnersPanelEnabled(), "Owners panel is enabled");
+		soft.assertTrue(popup.isDomainsPanelEnabled(), "Domain panel is enabled");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "EDT-60")
+	public void newMetadataIcon(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+
+		ServiceMetadataPopup popup = row0.clickAddMetadata();
+
+		soft.assertTrue(row0.getParticipantIdentifier().equalsIgnoreCase(popup.getParticipantIdentifierValue()), "Popup opened for apropriate service group");
+
+		soft.assertTrue(popup.isDocumentIdentifierEnabled());
+		soft.assertTrue(popup.isDocumentSchemeEnabled());
+
+		soft.assertAll();
+	}
+
+
+//	Cannot identify the cause of failure so move on and hope for the best
+
+	@Test(description = "EDT-70")
+	public void noSYSADMINOwners(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0;
+
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+		grid.doubleClickRow(index);
+
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+
+		popup.waitForXMillis(5000);
+
+		List<String> listedOptions = popup.ownersPanel.getOptions();
+		List<String> sysadmins = SMPRestClient.getSysAdmins();
+
+		for (String sysadmin : sysadmins) {
+			logger.info("Checking sysadmin " + sysadmin);
+			for (String listedOption : listedOptions) {
+				if(listedOption.equalsIgnoreCase(sysadmin)){
+					soft.fail("Found sysadmin between options for SG owners - " + sysadmin);
+				}
+			}
+		}
+		soft.assertAll();
+
+	}
+
+	@Test(description = "EDT-80")
+	public void allDomainsInDomainsAccordionSection(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupGrid grid = page.getGrid();
+
+		Integer index = 0 ;
+
+		ServiceGroupRowE row0 = grid.getRowsAs(ServiceGroupRowE.class).get(index);
+		grid.doubleClickRow(index);
+
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+		popup.domainsPanel.expandSection();
+
+		List<String> listedOptions = popup.domainsPanel.getOptions();
+		List<String> domains = SMPRestClient.getDomainAndSubdomain();
+
+		for (String domain : domains) {
+			boolean found = false;
+			logger.info("Checking domain " + domain);
+			for (String listedOption : listedOptions) {
+				if(listedOption.equalsIgnoreCase(domain)){
+					found= true;
+				}
+			}
+			soft.assertTrue(found, "Domain found in options - " + domain);
+		}
+
+
+		soft.assertAll();
+
+	}
+
+	@Test(description = "EDT-90")
+	public void extensionValidatedOnOK(){
+		String identifier = Generator.randomAlphaNumeric(7);
+		String scheme = Generator.randomAlphaNumeric(7);
+
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupPopup popup = page.clickNew();
+		popup.fillParticipanIdentifier(identifier);
+		popup.fillParticipanScheme(scheme);
+		popup.chooseFirstOwner();
+		popup.chooseFirstDomain();
+		popup.fillExtensionArea("invalid XML text");
+		popup.clickOK();
+
+		soft.assertTrue(!popup.getErrorMessage().isEmpty(), "Erorr message displayed when entering invalid xml in extension area");
+
+		popup.generateRndExtension();
+		popup.clickOK();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is now active");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is now active");
+
+		page.clickSave().confirm();
+
+		soft.assertTrue(!page.isSaveButtonEnabled(), "Save button is now inactive after save");
+		soft.assertTrue(!page.isCancelButtonEnabled(), "Cancel button is now inactive after save");
+
+		page.filterArea.filter(identifier, scheme, "");
+		soft.assertTrue(page.getGrid().getRows().get(0).getParticipantIdentifier().equalsIgnoreCase(identifier)
+				, "Service group was saved and is visible in search");
+
+
+		identifier = Generator.randomAlphaNumeric(10);
+		scheme = Generator.randomAlphaNumeric(10);
+
+		popup = page.clickNew();
+		popup.fillParticipanIdentifier(identifier);
+		popup.fillParticipanScheme(scheme);
+		popup.chooseFirstOwner();
+		popup.chooseFirstDomain();
+		popup.clickOK();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is now active (2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is now active (2)");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+
+		soft.assertTrue(!page.isSaveButtonEnabled(), "Save button is now inactive after cancel");
+		soft.assertTrue(!page.isCancelButtonEnabled(), "Cancel button is now inactive after cancel");
+
+		page.filterArea.filter(identifier, scheme, "");
+		soft.assertTrue(page.getGrid().getRowsNo() == 0
+				, "Service group was NOT saved and is NOT visible in search");
+
+		soft.assertAll();
+
+	}
+
+	@Test(description = "EDT-100")
+	public void deleteServiceGroup(){
+		SoftAssert soft = new SoftAssert();
+		EditPage page = new EditPage(driver);
+
+		ServiceGroupRowE row0 = page.getGrid().getRowsAs(ServiceGroupRowE.class).get(0);
+		String identifier = row0.getParticipantIdentifier();
+		row0.clickDelete();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is now active");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is now active");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+
+		page.filterArea.filter(identifier, "", "");
+		soft.assertTrue(page.getGrid().getRows().get(0).getParticipantIdentifier().equalsIgnoreCase(identifier)
+				, "Service group was not deleted and is visible in search");
+
+		page.refreshPage();
+		ServiceGroupGrid grid = page.getGrid();
+		row0 = grid.getRowsAs(ServiceGroupRowE.class).get(0);
+		identifier = row0.getParticipantIdentifier();
+
+		grid.selectRow(0);
+
+		soft.assertTrue(page.isDeleteButtonEnabled(), "After row select Delete button is enabled");
+
+		page.clickDelete();
+
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is now active (2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is now active (2)");
+
+		page.clickSave().confirm();
+
+		page.filterArea.filter(identifier, "", "");
+		soft.assertTrue(page.getGrid().getRowsNo() == 0
+				, "Service group deleted and is NOT visible in search anymore");
+
+		soft.assertAll();
+
+	}
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/LoginPgTest.java b/smp-ui-tests/src/test/java/ui/LoginPgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..796f0f499552e50bb0aa3392d31e04fe7a0657dc
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/LoginPgTest.java
@@ -0,0 +1,152 @@
+package ui;
+
+import org.testng.SkipException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.messageArea.AlertMessage;
+import pages.service_groups.search.SearchPage;
+import pages.components.baseComponents.SMPPage;
+import pages.login.LoginPage;
+import utils.enums.SMPMessages;
+
+import java.util.HashMap;
+
+public class LoginPgTest extends BaseTest {
+
+
+
+	@AfterMethod
+	public void logoutAndReset(){
+
+		SearchPage page = new SearchPage(driver);
+
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+
+		logger.info("Going to Search page");
+		page.sidebar.goToPage(SearchPage.class);
+	}
+
+	@Test(description = "LGN-0")
+	public void loginPageNavigation(){
+
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		logger.info("Going to login page");
+		page.pageHeader.goToLogin();
+		LoginPage loginPage = new LoginPage(driver);
+
+		logger.info("Checking that login page is loaded correctly!");
+		soft.assertTrue(loginPage.isLoaded(), "Login page elements are loaded!");
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "LGN-10")
+	public void loginPageBuildNumberTest(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		logger.info("Going to login page");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		logger.info("Check that the area for the build version is not empty");
+		soft.assertFalse(loginPage.getListedSMPVersion().isEmpty(), "Check that there is something in the build number area");
+
+		soft.assertAll();
+	}
+
+
+
+
+	@Test(description = "LGN-20")
+	public void loginPageDisplayTest(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+
+		logger.info("Going to login page");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+
+		soft.assertTrue(loginPage.isLoaded());
+
+		soft.assertTrue(loginPage.getTextInPasswordInput().isEmpty(), "User input is empty by default");
+		soft.assertTrue(loginPage.getTextInUsernameInput().isEmpty(), "Password input is empty by default");
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible");
+
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible(), "Edit link is not visible");
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is not visible");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is not visible");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "LGN-30")
+	public void successfulLogin(){
+		SoftAssert soft = new SoftAssert();
+
+		SMPPage page = new SMPPage(driver);
+		logger.info("Going to login page");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		HashMap<String, String> user = testDataProvider.getUserWithRole("SYS_ADMIN");
+		SearchPage searchPage = loginPage.login(user.get("username"), user.get("password"));
+
+
+		soft.assertTrue(searchPage.pageHeader.sandwichMenu.isLoggedIn(), "User is logged in");
+
+		soft.assertTrue(searchPage.isLoaded(), "Search page is loaded");
+
+		soft.assertAll();
+	}
+
+
+//	Tests that using invalid credentials leads to proper error message
+	@Test(description = "LGN-40")
+	public void unsuccessfulLogin(){
+		SoftAssert soft = new SoftAssert();
+
+		SMPPage page = new SMPPage(driver);
+		logger.info("Going to login page");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+
+		loginPage.login("inavlaidUsername", "inexistentPassword");
+
+		AlertMessage message = loginPage.alertArea.getAlertMessage();
+		soft.assertTrue(message.isError(), "Check message is error message");
+		soft.assertEquals(message.getMessage(), SMPMessages.MSG_1, "Check the error message content");
+
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is still available in the sidebar");
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible(), "Edit link is NOT available in the sidebar");
+
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT available in the sidebar");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT available in the sidebar");
+
+
+		soft.assertAll();
+	}
+
+//	This will serve as a reminder to check this message manually
+	@Test(description = "LGN-50")
+	public void SMPNotRunningTest(){
+		throw new SkipException("This test will be executed manually !!!");
+	}
+
+
+
+
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/PrivilegesTests.java b/smp-ui-tests/src/test/java/ui/PrivilegesTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..e09974dac28dda6a5195f7f3335734804e620a2a
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/PrivilegesTests.java
@@ -0,0 +1,194 @@
+package ui;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.baseComponents.SMPPage;
+import pages.service_groups.edit.EditPage;
+import pages.service_groups.edit.ServiceGroupPopup;
+import pages.login.LoginPage;
+import pages.service_groups.search.SearchPage;
+import utils.Generator;
+import utils.rest.SMPRestClient;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class PrivilegesTests extends BaseTest {
+
+
+	@AfterMethod
+	public void logoutAndReset(){
+		SMPPage page = new SMPPage(driver);
+		page.refreshPage();
+
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+	}
+
+	@Test(description = "RGT-0")
+	public void anonymousUserRights(){
+		logger.info("Checking rights for anonymous user");
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+
+		soft.assertTrue(page.sidebar.isSearchLnkVisible(), "Search link is visible on Search page");
+		soft.assertFalse(page.sidebar.isEditLnkVisible(), "Edit link is NOT visible on Search page");
+		soft.assertFalse(page.sidebar.isDomainLnkVisible(), "Domain link is NOT visible on Search page");
+		soft.assertFalse(page.sidebar.isUsersLnkVisible(), "Users link is NOT visible on Search page");
+
+		logger.info("Going to the login page");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible on Login page");
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible(), "Edit link is NOT visible on Login page");
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT visible on Login page");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT visible on Login page");
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "RGT-10")
+	public void sg_adminRights(){
+
+		String pi = Generator.randomAlphaNumeric(10);
+		String ps = Generator.randomAlphaNumeric(10);
+
+		SMPRestClient.createServiceGroup(pi, ps,
+				new ArrayList<>(Arrays.asList("user")),
+				new ArrayList<>(Arrays.asList("domainNoble", "domainEPREL"))
+		);
+
+		logger.info("Checking rights for SG_ADMIN user");
+		SoftAssert soft = new SoftAssert();
+
+		SMPPage page = new SMPPage(driver);
+		logger.info("going to login");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		HashMap<String, String> user = testDataProvider.getUserWithRole("SG_ADMIN");
+
+		logger.info("Logging in with user " + user.get("username"));
+		loginPage.login(user.get("username"), user.get("password"));
+
+		soft.assertTrue(loginPage.pageHeader.sandwichMenu.isLoggedIn(), "Check that the user is logged in");
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible after login for SG_ADMIN");
+		soft.assertTrue(loginPage.sidebar.isEditLnkVisible(), "Edit link is visible after login for SG_ADMIN");
+
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT visible after login for SG_ADMIN");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT visible after login for SG_ADMIN");
+
+//		going to check privileges on Edit page for SG_ADMIN
+		logger.info("Going to edit page");
+		EditPage editPage = loginPage.sidebar.goToPage(EditPage.class);
+		soft.assertFalse(editPage.isNewButtonPresent(), "New button should not be present for SG_ADMIN");
+		soft.assertFalse(editPage.isDeleteButtonPresent(), "Delete button should not be present for SG_ADMIN");
+
+		logger.info("opening service group popup");
+		editPage.getGrid().doubleClickRow(0);
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+
+		soft.assertFalse(popup.isDomainsPanelEnabled(), "SG_ADMIN cannot edit a service groups DOMAINS");
+		soft.assertFalse(popup.isOwnersPanelPresent(), "SG_ADMIN cannot edit a service groups OWNERS");
+		popup.clickCancel();
+
+		logger.info("LOGOUT");
+		loginPage.pageHeader.sandwichMenu.logout();
+
+		soft.assertFalse(loginPage.pageHeader.sandwichMenu.isLoggedIn(), "Check that the user is logged out");
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible after logout");
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible(), "Edit link is NOT visible after logout");
+
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT visible after logout");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT visible after logout");
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "RGT-20")
+	public void sys_adminRights(){
+		SoftAssert soft = new SoftAssert();
+
+		SMPPage page = new SMPPage(driver);
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		HashMap<String, String> user = testDataProvider.getUserWithRole("SYS_ADMIN");
+		loginPage.login(user.get("username"), user.get("password"));
+
+		soft.assertTrue(loginPage.pageHeader.sandwichMenu.isLoggedIn());
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible());
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible());
+
+		soft.assertTrue(loginPage.sidebar.isDomainLnkVisible());
+		soft.assertTrue(loginPage.sidebar.isUsersLnkVisible());
+
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "RGT-30")
+	public void smp_adminRights(){
+		logger.info("Checking rights for SMP_ADMIN user");
+		SoftAssert soft = new SoftAssert();
+
+		SMPPage page = new SMPPage(driver);
+		logger.info("going to login");
+		page.pageHeader.goToLogin();
+
+		LoginPage loginPage = new LoginPage(driver);
+		HashMap<String, String> user = testDataProvider.getUserWithRole("SMP_ADMIN");
+
+		logger.info("Logging in with user " + user.get("username"));
+		loginPage.login(user.get("username"), user.get("password"));
+
+		soft.assertTrue(loginPage.pageHeader.sandwichMenu.isLoggedIn(), "Check that the user is logged in");
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible after login for SMP_ADMIN");
+		soft.assertTrue(loginPage.sidebar.isEditLnkVisible(), "Edit link is visible after login for SMP_ADMIN");
+
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT visible after login for SMP_ADMIN");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT visible after login for SMP_ADMIN");
+
+//		going to check privileges on Edit page for SMP_ADMIN
+		logger.info("Going to edit page");
+		EditPage editPage = loginPage.sidebar.goToPage(EditPage.class);
+		soft.assertTrue(editPage.isNewButtonPresent(), "New button should be present for SMP_ADMIN");
+		soft.assertTrue(editPage.isDeleteButtonPresent(), "Delete button should be present for SMP_ADMIN");
+
+		logger.info("opening service group popup");
+		editPage.getGrid().doubleClickRow(0);
+		ServiceGroupPopup popup = new ServiceGroupPopup(driver);
+
+		soft.assertTrue(popup.isDomainsPanelEnabled(), "SMP_ADMIN should be able to edit a service groups DOMAINS");
+		soft.assertTrue(popup.isOwnersPanelEnabled(), "SMP_ADMIN should be able to edit a service groups OWNERS");
+		popup.clickCancel();
+
+		logger.info("LOGOUT");
+		loginPage.pageHeader.sandwichMenu.logout();
+
+		soft.assertFalse(loginPage.pageHeader.sandwichMenu.isLoggedIn(), "Check that the user is logged out");
+
+		soft.assertTrue(loginPage.sidebar.isSearchLnkVisible(), "Search link is visible after logout");
+		soft.assertFalse(loginPage.sidebar.isEditLnkVisible(), "Edit link is NOT visible after logout");
+
+		soft.assertFalse(loginPage.sidebar.isDomainLnkVisible(), "Domain link is NOT visible after logout");
+		soft.assertFalse(loginPage.sidebar.isUsersLnkVisible(), "Users link is NOT visible after logout");
+
+		soft.assertAll();
+	}
+
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/SearchPgTest.java b/smp-ui-tests/src/test/java/ui/SearchPgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b28a4dd6045c08555bb1a1d4100c0f77dbc1200
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/SearchPgTest.java
@@ -0,0 +1,303 @@
+package ui;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Ignore;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.baseComponents.SMPPage;
+import pages.login.LoginPage;
+import pages.service_groups.MetadataGrid;
+import pages.service_groups.MetadataRow;
+import pages.service_groups.ServiceGroupRow;
+import pages.service_groups.edit.EditPage;
+import pages.service_groups.search.SearchPage;
+import pages.service_groups.search.pojo.ServiceGroup;
+import utils.Generator;
+import utils.rest.SMPRestClient;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+public class SearchPgTest extends BaseTest {
+
+	@AfterMethod
+	public void resetFilters(){
+		new SMPPage(driver).refreshPage();
+	}
+
+	@Test(description = "SRCH-0")
+	public void searchPgInitialState(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+		soft.assertTrue(page.filters.getParticipantIdentifierInputValue().isEmpty());
+		soft.assertTrue(page.filters.getParticipantSchemeInputValue().isEmpty());
+		soft.assertEquals(page.filters.domainSelect.getSelectedValue(), "All Domains");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-10")
+	public void domainSelectContent(){
+		SoftAssert soft = new SoftAssert();
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		List<String> uiDomains = page.filters.domainSelect.getOptionTexts();
+		List<String> restDomains = SMPRestClient.getDomainAndSubdomain();
+
+		for (String restDomain : restDomains) {
+			boolean found = false;
+			for (String uiDomain : uiDomains) {
+				if(uiDomain.equalsIgnoreCase(restDomain)){
+					found = true;
+				}
+			}
+			soft.assertTrue(found, "Domain was found in domain dropdown " + restDomain);
+		}
+
+		soft.assertAll();
+
+	}
+
+	@Test(description = "SRCH-20")
+	public void searchGridInitialState(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		List<String> headers = page.serviceGroupGrid.getHeaders();
+		soft.assertTrue(headers.contains("Participant identifier"));
+		soft.assertTrue(headers.contains("Participant scheme"));
+		soft.assertTrue(headers.contains("OASIS ServiceGroup URL"));
+		soft.assertTrue(headers.contains("Metadata size"));
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-30")
+	public void searchFilterResults(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		ServiceGroupRow row0 = page.serviceGroupGrid.getRows().get(0);
+		String pScheme = row0.getParticipantScheme();
+		String pIdentifier = row0.getParticipantIdentifier();
+
+//		looking for exact match
+		page.filters.filter(pIdentifier, pScheme, "");
+
+		List<ServiceGroupRow> rows = page.serviceGroupGrid.getRows();
+
+		for (ServiceGroupRow row : rows) {
+			soft.assertTrue(row.getParticipantIdentifier().contains(pIdentifier));
+			soft.assertTrue(row.getParticipantScheme().contains(pScheme));
+		}
+
+//		Search for substring
+		page.filters.filter(pIdentifier.substring(2), pScheme.substring(2), "");
+		rows = page.serviceGroupGrid.getRows();
+
+		for (ServiceGroupRow row : rows) {
+
+			String identifier =row.getParticipantIdentifier();
+			String scheme =row.getParticipantScheme();
+
+			soft.assertTrue(identifier.contains(pIdentifier), String.format("Identifier %s, found %s", pIdentifier, identifier));
+			soft.assertTrue(scheme.contains(pScheme), String.format("Scheme %s, found %s", pScheme, scheme));
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-40")
+	public void openURLLink(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		ServiceGroupRow row0 = page.serviceGroupGrid.getRows().get(0);
+		String listedURL = row0.getServiceGroupURL();
+		String pScheme = row0.getParticipantScheme();
+		String pIdentifier = row0.getParticipantIdentifier();
+
+//		verify proper URL format
+		String tmpURLPart = listedURL.split("smp/")[1].trim();
+		soft.assertEquals(tmpURLPart, pScheme+"::"+pIdentifier, "URL contians the proper scheme and identifier");
+
+		ServiceGroup serviceGroup = SMPRestClient.getServiceGroup(listedURL);
+
+		soft.assertTrue(row0.getMetadataSize() == serviceGroup.getServiceMetadataReferenceCollection().size(),
+				"Number of listed MetadataReferecences in XML matches UI");
+
+
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "SRCH-50") @Ignore
+	public void expandServiceGroupCheckMetadata(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		ServiceGroupRow row0 = page.serviceGroupGrid.getRows().get(0);
+		String listedURL = row0.getServiceGroupURL();
+		String pScheme = row0.getParticipantScheme();
+		String pIdentifier = row0.getParticipantIdentifier();
+
+//		verify proper URL format
+		ServiceGroup serviceGroup = SMPRestClient.getServiceGroup(listedURL);
+
+		MetadataGrid metadataGrid = row0.expandMetadata();
+
+		List<MetadataRow> metadataRows = metadataGrid.getMetadataRows();
+
+		soft.assertTrue(row0.getMetadataSize() == metadataRows.size(), "Metadata size field compared with the size of the list containing the metadata");
+
+		for (MetadataRow metadataRow : metadataRows) {
+			String docScheme = metadataRow.getDocumentIdentifierScheme();
+			String docId = metadataRow.getDocumentIdentifier();
+			String url = metadataRow.getURL();
+
+			soft.assertTrue(url.contains(String.format("%s::%s/services/%s::%s", pScheme, pIdentifier, docScheme, docId)), "Checking URL format for metadata "+ docId);
+
+
+			String metadata = SMPRestClient.getMetadataString(url);
+
+			soft.assertTrue(metadata.contains(pScheme), "Checking XML contains proper participant scheme for metadata "+ docId);
+			soft.assertTrue(metadata.contains(pIdentifier), "Checking XML contains proper participant ID for metadata "+ docId);
+			soft.assertTrue(metadata.toLowerCase().contains(docId.toLowerCase()), "Checking XML contains proper document ID for metadata "+ docId);
+			soft.assertTrue(metadata.contains(docScheme), "Checking XML contains proper document scheme for metadata "+ docId);
+
+
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-60")
+	public void collapseMetadata(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		ServiceGroupRow row0 = page.serviceGroupGrid.getRows().get(0);
+
+		soft.assertTrue(row0.getExpandButtonText().contains("+"), "Initially the row has + on it");
+		row0.expandMetadata();
+
+		soft.assertTrue(row0.getExpandButtonText().contains("-"), "Row has - on it after first click");
+
+		row0.collapseMetadata();
+		soft.assertTrue(row0.getExpandButtonText().contains("+"), "Row has + on it after collapse");
+		soft.assertFalse(row0.isMetadataExpanded(), "Metadata table is not present no more");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-70")
+	public void verifyOpenMetadataURL(){
+		SoftAssert soft = new SoftAssert();
+
+		SearchPage page = new SearchPage(driver);
+		soft.assertTrue(page.isLoaded());
+
+		ServiceGroupRow row0 = page.serviceGroupGrid.getRows().get(0);
+		String listedURL = row0.getServiceGroupURL();
+		String pScheme = row0.getParticipantScheme();
+		String pIdentifier = row0.getParticipantIdentifier();
+
+//		verify proper URL format
+		ServiceGroup serviceGroup = SMPRestClient.getServiceGroup(listedURL);
+
+		MetadataGrid metadataGrid = row0.expandMetadata();
+
+		List<MetadataRow> metadataRows = metadataGrid.getMetadataRows();
+
+		soft.assertTrue(row0.getMetadataSize() == metadataRows.size(), "Metadata size field compared with the size of the list containing the metadata");
+
+		for (MetadataRow metadataRow : metadataRows) {
+			String docScheme = metadataRow.getDocumentIdentifierScheme();
+			String docId = metadataRow.getDocumentIdentifier();
+			String url = metadataRow.getURL();
+
+			soft.assertTrue(url.contains(String.format("%s::%s/services/%s::%s", pScheme, pIdentifier, docScheme, docId)), "Checking URL format for metadata "+ docId);
+
+			String mainWindow = driver.getWindowHandle();
+
+			metadataRow.clickURL();
+			page.waitForNumberOfWindowsToBe(2);
+			Set<String> handleSet = driver.getWindowHandles();
+			String[] handles = handleSet.toArray(new String[handleSet.size()]);
+
+			soft.assertTrue(handles.length == 2);
+
+			driver.switchTo().window(handles[1]);
+			driver.close();
+			driver.switchTo().window(handles[0]);
+
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "SRCH-80")
+	public void filterByDifferentDomains(){
+		SoftAssert soft = new SoftAssert();
+		SearchPage page = new SearchPage(driver);
+
+		page.pageHeader.goToLogin();
+		LoginPage loginPage = new LoginPage(driver);
+		loginPage.login("SMP_ADMIN");
+		EditPage editPage = loginPage.sidebar.goToPage(EditPage.class);
+
+		String participantID = Generator.randomAlphaNumeric(5);
+		String participantScheme = Generator.randomAlphaNumeric(5);
+
+		List<String> domains = Arrays.asList("domain1 (peppol)", "domain (subdomain)");
+		List<String> owners = Arrays.asList("smp");
+
+		logger.info("Creating servicegroup with participan id: " + participantID);
+		editPage.addNewSerivceGroup(participantID,
+				participantScheme,
+				owners,	domains, "");
+
+		editPage.saveChanges();
+
+		SearchPage searchPage = editPage.sidebar.goToPage(SearchPage.class);
+
+		searchPage.filters.filter(participantID, participantScheme, "domain (subdomain)");
+		List<ServiceGroupRow> results = searchPage.serviceGroupGrid.getRows();
+
+		soft.assertTrue(results.size() == 1, "Results size is 1 (first search)");
+		soft.assertTrue(results.get(0).getParticipantIdentifier().equalsIgnoreCase(participantID),
+				"First and only result is the one we entered and is found when filtering by first domain");
+
+
+		searchPage.filters.filter(participantID, participantScheme, "domain1 (peppol)");
+		results = searchPage.serviceGroupGrid.getRows();
+
+		soft.assertTrue(results.size() == 1, "Results size is 1 (second search)");
+		soft.assertTrue(results.get(0).getParticipantIdentifier().equalsIgnoreCase(participantID),
+				"First and only result is the one we entered and is found when filtering by second domain");
+
+
+
+		editPage.waitForXMillis(2000);
+		soft.assertAll();
+	}
+
+
+
+
+}
diff --git a/smp-ui-tests/src/test/java/ui/UsersPgTest.java b/smp-ui-tests/src/test/java/ui/UsersPgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..344535f38a7ddc9b62ad47cb665128d26a5f0afa
--- /dev/null
+++ b/smp-ui-tests/src/test/java/ui/UsersPgTest.java
@@ -0,0 +1,500 @@
+package ui;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Ignore;
+import org.testng.annotations.Test;
+import org.testng.asserts.SoftAssert;
+import pages.components.ConfirmationDialog;
+import pages.components.baseComponents.SMPPage;
+import pages.components.messageArea.AlertMessage;
+import pages.users.UserPopup;
+import pages.users.UserRowInfo;
+import pages.users.UsersPage;
+import utils.Generator;
+import utils.TestDataProvider;
+import utils.enums.SMPMessages;
+import utils.rest.SMPRestClient;
+
+import javax.security.auth.login.Configuration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class UsersPgTest extends BaseTest {
+	
+	
+	@AfterMethod
+	public void logoutAndReset(){
+		SMPPage page = new SMPPage(driver);
+		page.refreshPage();
+		
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+	}
+	
+	
+	@BeforeMethod
+	public void loginAndGoToUsersPage(){
+		
+		SMPPage page = new SMPPage(driver);
+
+		if(page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Logout!!");
+			page.pageHeader.sandwichMenu.logout();
+		}
+		
+		if(!page.pageHeader.sandwichMenu.isLoggedIn()){
+			logger.info("Login!!");
+			page.pageHeader.goToLogin().login("SYS_ADMIN");
+		}
+		
+		logger.info("Going to Users page");
+		page.sidebar.goToPage(UsersPage.class);
+	}
+	
+	@Test(description = "USR-10")
+	public void newUser(){
+		String username = Generator.randomAlphaNumeric(10);
+		String validPass = "QW!@qw12";
+		
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage usersPage = new UsersPage(driver);
+		
+//		soft.assertTrue(usersPage.isNewButtonEnabled(), "New button should be enabled");
+		
+		UserPopup popup = usersPage.clickNew();
+		soft.assertTrue(!popup.isOKButtonActive(), "OK button should be disabled until valid data is filled in the popup");
+		
+		popup.rolesSelect.selectOptionWithText("SYSTEM_ADMIN");
+		
+		popup.clickUserDetailsToggle();
+
+		popup.fillDetailsForm(username, validPass, validPass);
+		popup.clickOK();
+
+		soft.assertTrue(usersPage.isSaveButtonEnabled(), "Save button is enabled");
+		soft.assertTrue(usersPage.isCancelButtonEnabled(), "Cancel button is enabled");
+
+		usersPage.clickSave().confirm();
+
+		soft.assertTrue(!usersPage.alertArea.getAlertMessage().isError(), "Message listed is success");
+		soft.assertTrue(usersPage.alertArea.getAlertMessage().getMessage().equalsIgnoreCase(SMPMessages.MSG_18), "Message listed is as expected");
+
+		soft.assertTrue(isUserListed(username), "User present in the page");
+
+		soft.assertAll();
+	}
+
+
+	@Test(description = "USR-20")
+	public void usernameValidation(){
+		String username = Generator.randomAlphaNumeric(10);
+		String validPass = "QW!@qw12";
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage usersPage = new UsersPage(driver);
+		UserPopup popup = usersPage.clickNew();
+		soft.assertTrue(!popup.isOKButtonActive(), "OK button should be disabled until valid data is filled in the popup");
+
+		popup.rolesSelect.selectOptionWithText("SMP_ADMIN");
+
+		popup.clickUserDetailsToggle();
+
+		popup.fillDetailsForm("tst", validPass, validPass);
+		soft.assertTrue(!popup.isOKButtonActive(), "OK button should be disabled until valid data is filled in the popup(2)");
+		soft.assertEquals(popup.getUsernameValidationEror(), SMPMessages.USERNAME_VALIDATION_MESSAGE, "Validation error message is displayed(2)");
+		popup.fillDetailsForm("#$^&*^%&$#@%@$#%$", validPass, validPass);
+		soft.assertTrue(!popup.isOKButtonActive(), "OK button should be disabled until valid data is filled in the popup(3)");
+		soft.assertEquals(popup.getUsernameValidationEror(), SMPMessages.USERNAME_VALIDATION_MESSAGE, "Validation error message is displayed(3)");
+		popup.fillDetailsForm("QWERQWERQWERQWERQWERQWERQWERQWE33", validPass, validPass);
+		soft.assertTrue(!popup.isOKButtonActive(), "OK button should be disabled until valid data is filled in the popup(4)");
+		soft.assertEquals(popup.getUsernameValidationEror(), SMPMessages.USERNAME_VALIDATION_MESSAGE, "Validation error message is displayed(4)");
+
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-30")
+	public void passwordValidation(){
+
+		ArrayList<String> passToValidate = new ArrayList<>(Arrays.asList("qwqw",
+//				"QWERQWERQWERQWERQWERQWERQWERQWE33",
+//				"QWERTYUIOP",
+//				"qwertyuiop",
+//				"321654987",
+//				"~!@#$%^&*()_",
+//				"~1Aa#",
+				"~1a#2d2dds"));
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage usersPage = new UsersPage(driver);
+
+		for (String pass : passToValidate) {
+			usersPage.refreshPage();
+//			usersPage.clickVoidSpace();
+//			usersPage.waitForXMillis(5000);
+			UserPopup popup = usersPage.clickNew();
+			popup.rolesSelect.selectOptionWithText("SMP_ADMIN");
+			popup.clickUserDetailsToggle();
+
+			popup.fillDetailsForm("test11", pass, pass);
+			soft.assertTrue(!popup.isOKButtonActive(), String.format("OK button should be disabled until valid data is filled in the popup - %s ", pass));
+			soft.assertEquals(popup.getPassValidationEror(), SMPMessages.PASS_POLICY_MESSAGE, String.format("Pass policy message is displayed - %s", pass));
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-40")
+	public void listedRoles(){
+
+		ArrayList<String> expectedRoleValues = new ArrayList<>(Arrays.asList("SYSTEM_ADMIN", "SMP_ADMIN", "SERVICE_GROUP_ADMIN"));
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage usersPage = new UsersPage(driver);
+		UserPopup popup = usersPage.clickNew();
+		List<String> listedRoles = popup.rolesSelect.getOptionTexts();
+
+		soft.assertTrue(expectedRoleValues.size() == listedRoles.size(), "Number of roles is the same as expected");
+
+		for (String expected : expectedRoleValues) {
+			boolean found = false;
+			for (String listedRole : listedRoles) {
+				if(listedRole.equalsIgnoreCase(expected)){
+					found = true;
+				}
+			}
+			soft.assertTrue(found, "Role found in page " + expected);
+		}
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-50")
+	public void deleteSYS_ADMIN(){
+
+		String username = Generator.randomAlphaNumeric(10);
+		SMPRestClient.createUser(username, "SYSTEM_ADMIN");
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled");
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+		soft.assertTrue(isUserListed(username), "After canceling delete user is still listed");
+
+
+		index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select(2)");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted(2)");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted(2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted(2)");
+
+		page.clickSave().confirm();
+
+		soft.assertTrue(page.alertArea.getAlertMessage().getMessage().equalsIgnoreCase(SMPMessages.MSG_18), "Message listed is as expected");
+		soft.assertTrue(!isUserListed(username), "After saving deleted user is not listed");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-60")
+	public void changeRoleSYS_ADMIN(){
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		int index = scrollToUserWithRole("SYSTEM_ADMIN");
+
+		page.grid().selectRow(index);
+		UserPopup popup = page.clickEdit();
+		List<String> options = popup.rolesSelect.getOptionTexts();
+		soft.assertTrue(options.size() == 1, "Role dropdown has only one value");
+		soft.assertTrue(options.get(0).equalsIgnoreCase("SYSTEM_ADMIN"), "Role dropdown has only one value and that is \"SYSTEM_ADMIN\"");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-70")
+	public void changeRoleNON_SYS_ADMIN(){
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		int index = scrollToUserWithRole("SMP_ADMIN");
+
+		page.grid().selectRow(index);
+		UserPopup popup = page.clickEdit();
+
+		List<String> options = popup.rolesSelect.getOptionTexts();
+		soft.assertTrue(options.size() == 2, "Role dropdown has only two values");
+		soft.assertTrue(options.get(0).equalsIgnoreCase("SMP_ADMIN"), "Role dropdown has value \"SMP_ADMIN\"");
+		soft.assertTrue(options.get(1).equalsIgnoreCase("SERVICE_GROUP_ADMIN"), "Role dropdown has value \"SERVICE_GROUP_ADMIN\"");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-80")
+	public void deleteOWNUserRecord(){
+
+		String username = new TestDataProvider().getUserWithRole("SYS_ADMIN").get("username");
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled");
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		AlertMessage message = page.alertArea.getAlertMessage();
+		soft.assertTrue(message.isError(), "Listed message is error");
+		soft.assertTrue(message.getMessage().equalsIgnoreCase(SMPMessages.USER_OWN_DELETE_ERR), "Listed message has appropriate text");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-90")
+	public void deleteSMP_ADMIN(){
+
+		String username = Generator.randomAlphaNumeric(10);
+		SMPRestClient.createUser(username, "SMP_ADMIN");
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled");
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+		soft.assertTrue(isUserListed(username), "After canceling delete user is still listed");
+
+
+		index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select(2)");
+
+		page.clickDelete();
+		page.waitForXMillis(200);
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted(2)");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted(2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted(2)");
+
+		page.clickSave().confirm();
+
+		soft.assertTrue(page.alertArea.getAlertMessage().getMessage().equalsIgnoreCase(SMPMessages.MSG_18), "Message is as expected");
+		soft.assertTrue(!isUserListed(username), "After saving deleted user is not listed");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-100")
+	public void deleteSERVICE_GROUP_ADMIN(){
+
+		String username = Generator.randomAlphaNumeric(10);
+		SMPRestClient.createUser(username, "SERVICE_GROUP_ADMIN");
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled");
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted");
+
+		page.clickCancel().confirm();
+		new ConfirmationDialog(driver).confirm();
+		soft.assertTrue(isUserListed(username), "After canceling delete user is still listed");
+
+
+		index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select(2)");
+
+		page.clickDelete();
+		soft.assertTrue(!page.isDeleteButtonEnabled(), "Delete button is not enabled after user is deleted(2)");
+		soft.assertTrue(page.isSaveButtonEnabled(), "Save button is enabled after user is deleted(2)");
+		soft.assertTrue(page.isCancelButtonEnabled(), "Cancel button is enabled after user is deleted(2)");
+
+		page.clickSave().confirm();
+
+		soft.assertTrue(page.alertArea.getAlertMessage().getMessage().equalsIgnoreCase(SMPMessages.MSG_18), "Message is as expected");
+		soft.assertTrue(!isUserListed(username), "After saving deleted user is not listed");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-110")
+	public void deleteSG_ADMINWithSG(){
+
+		String username = Generator.randomAlphaNumeric(10);
+		String pi = Generator.randomAlphaNumeric(10);
+		String ps = Generator.randomAlphaNumeric(10);
+
+		String expectedErrorMess = String.format("Delete validation error Could not delete user with ownerships! User: %s owns SG count: 1.", username);
+
+		SMPRestClient.createUser(username, "SERVICE_GROUP_ADMIN");
+		SMPRestClient.createServiceGroup(pi, ps,
+				new ArrayList<>(Arrays.asList(username)),
+				new ArrayList<>(Arrays.asList("domainNoble", "domainEPREL"))
+		);
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		AlertMessage message = page.alertArea.getAlertMessage();
+		soft.assertTrue(message.isError(), "Page shows error message when deleting user with SG");
+		soft.assertTrue(message.getMessage().equalsIgnoreCase(expectedErrorMess), "Desired message appears");
+
+		soft.assertAll();
+	}
+
+	@Test(description = "USR-120")
+	public void deleteSMP_ADMINWithSG(){
+
+		String username = Generator.randomAlphaNumeric(10);
+		String pi = Generator.randomAlphaNumeric(10);
+		String ps = Generator.randomAlphaNumeric(10);
+
+		String expectedErrorMess = String.format("Delete validation error Could not delete user with ownerships! User: %s owns SG count: 1.", username);
+
+		SMPRestClient.createUser(username, "SMP_ADMIN");
+		SMPRestClient.createServiceGroup(pi, ps,
+				new ArrayList<>(Arrays.asList(username)),
+				new ArrayList<>(Arrays.asList("domainNoble", "domainEPREL"))
+		);
+
+		SoftAssert soft = new SoftAssert();
+
+		UsersPage page = new UsersPage(driver);
+
+		int index = scrollToUser(username);
+		page.grid().selectRow(index);
+		soft.assertTrue(page.isDeleteButtonEnabled(), "Delete button is enabled after row select");
+
+		page.clickDelete();
+		page.waitForXMillis(500);
+		AlertMessage message = page.alertArea.getAlertMessage();
+		soft.assertTrue(message.isError(), "Page shows error message when deleting user with SG");
+		soft.assertTrue(message.getMessage().equalsIgnoreCase(expectedErrorMess), "Desired message appears");
+
+		soft.assertAll();
+	}
+
+
+
+
+	private boolean isUserListed(String username){
+		boolean end = false;
+
+		UsersPage page = new UsersPage(driver);
+		page.pagination.skipToFirstPage();
+
+		while (!end) {
+			page = new UsersPage(driver);
+			List<UserRowInfo> rows = page.grid().getRows();
+
+			for (UserRowInfo row : rows) {
+				if(row.getUsername().equalsIgnoreCase(username)){
+					return true;
+				}
+			}
+
+			if(page.pagination.hasNextPage()){
+				page.pagination.goToNextPage();
+			}else{end = true;}
+		}
+
+		return false;
+	}
+
+	private int scrollToUser(String username){
+		UsersPage page = new UsersPage(driver);
+		page.pagination.skipToFirstPage();
+
+		boolean end = false;
+		while (!end) {
+			page = new UsersPage(driver);
+
+			List<UserRowInfo> rows = page.grid().getRows();
+			for (int i = 0; i < rows.size(); i++) {
+				if(rows.get(i).getUsername().equalsIgnoreCase(username)){
+					return i;
+				}
+			}
+
+			if(page.pagination.hasNextPage()){
+				page.pagination.goToNextPage();
+			}else{end = true;}
+		}
+
+		return -1;
+	}
+
+	private int scrollToUserWithRole(String role){
+		UsersPage page = new UsersPage(driver);
+		page.pagination.skipToFirstPage();
+
+		boolean end = false;
+		while (!end) {
+			page = new UsersPage(driver);
+
+			List<UserRowInfo> rows = page.grid().getRows();
+			for (int i = 0; i < rows.size(); i++) {
+				if(rows.get(i).getRole().equalsIgnoreCase(role)){
+					return i;
+				}
+			}
+
+			if(page.pagination.hasNextPage()){
+				page.pagination.goToNextPage();
+			}else{end = true;}
+		}
+
+		return -1;
+	}
+
+
+
+}