Add selenium test of login with OpenShift account (#10158)
Signed-off-by: Dmytro Nochevnov <dnochevnov@codenvy.com>6.19.x
parent
f80c1867fc
commit
7ce7635ab1
|
|
@ -17,14 +17,18 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import org.eclipse.che.selenium.core.CheSeleniumWebDriverRelatedModule;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.action.ActionsFactory;
|
||||
import org.eclipse.che.selenium.core.entrance.Entrance;
|
||||
import org.eclipse.che.selenium.core.pageobject.PageObjectsInjector;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.eclipse.che.selenium.core.webdriver.WebDriverWaitFactory;
|
||||
import org.eclipse.che.selenium.pageobject.site.CheLoginPage;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
@Singleton
|
||||
public class PageObjectsInjectorImpl extends PageObjectsInjector {
|
||||
@Inject private CheSeleniumWebDriverRelatedModule cheSeleniumWebDriverRelatedModule;
|
||||
@Inject private ActionsFactory actionsFactory;
|
||||
|
||||
@Inject
|
||||
@Named("che.multiuser")
|
||||
|
|
@ -32,11 +36,17 @@ public class PageObjectsInjectorImpl extends PageObjectsInjector {
|
|||
|
||||
@Override
|
||||
public Map<Class<?>, Object> getDependenciesWithWebdriver(SeleniumWebDriver seleniumWebDriver) {
|
||||
SeleniumWebDriverHelper seleniumWebDriverHelper =
|
||||
new SeleniumWebDriverHelper(
|
||||
seleniumWebDriver, new WebDriverWaitFactory(seleniumWebDriver), actionsFactory);
|
||||
|
||||
Map<Class<?>, Object> dependencies = new HashMap<>();
|
||||
dependencies.put(
|
||||
Entrance.class,
|
||||
cheSeleniumWebDriverRelatedModule.getEntrance(
|
||||
isMultiuser, new CheLoginPage(seleniumWebDriver), seleniumWebDriver));
|
||||
isMultiuser,
|
||||
new CheLoginPage(seleniumWebDriver, seleniumWebDriverHelper),
|
||||
seleniumWebDriver));
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.pageobject.ocp;
|
||||
|
||||
import static org.eclipse.che.selenium.pageobject.ocp.AuthorizeOpenShiftAccessPage.Locators.ALLOW_PERMISSIONS_BUTTON_NAME;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
public class AuthorizeOpenShiftAccessPage {
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
protected interface Locators {
|
||||
String ALLOW_PERMISSIONS_BUTTON_NAME = "approve";
|
||||
}
|
||||
|
||||
@FindBy(name = ALLOW_PERMISSIONS_BUTTON_NAME)
|
||||
private WebElement allowPermissionsButton;
|
||||
|
||||
@Inject
|
||||
public AuthorizeOpenShiftAccessPage(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
public void allowPermissions() {
|
||||
seleniumWebDriverHelper.waitAndClick(allowPermissionsButton);
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
public void waitOnOpen() {
|
||||
seleniumWebDriverHelper.waitVisibility(allowPermissionsButton);
|
||||
}
|
||||
|
||||
private void waitOnClose() {
|
||||
seleniumWebDriverHelper.waitInvisibility(allowPermissionsButton);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.pageobject.ocp;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage.Locators.LOGIN_BUTTON_XPATH;
|
||||
import static org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage.Locators.PASSWORD_INPUT_NAME;
|
||||
import static org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage.Locators.USERNAME_INPUT_NAME;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
public class OpenShiftLoginPage {
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
protected interface Locators {
|
||||
String USERNAME_INPUT_NAME = "username";
|
||||
String PASSWORD_INPUT_NAME = "password";
|
||||
String LOGIN_BUTTON_XPATH = "//button[contains(text(),'Log In')]";
|
||||
}
|
||||
|
||||
@FindBy(name = USERNAME_INPUT_NAME)
|
||||
private WebElement usernameInput;
|
||||
|
||||
@FindBy(name = PASSWORD_INPUT_NAME)
|
||||
private WebElement passwordInput;
|
||||
|
||||
@FindBy(xpath = LOGIN_BUTTON_XPATH)
|
||||
private WebElement loginButton;
|
||||
|
||||
@Inject
|
||||
public OpenShiftLoginPage(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
public void login(String username, String password) {
|
||||
waitOnOpen();
|
||||
|
||||
seleniumWebDriverHelper.setValue(usernameInput, username);
|
||||
seleniumWebDriverHelper.setValue(passwordInput, password);
|
||||
seleniumWebDriverHelper.waitAndClick(loginButton);
|
||||
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
private void waitOnOpen() {
|
||||
seleniumWebDriverHelper.waitAllVisibility(asList(usernameInput, passwordInput, loginButton));
|
||||
}
|
||||
|
||||
private void waitOnClose() {
|
||||
seleniumWebDriverHelper.waitAllInvisibility(asList(usernameInput, passwordInput, loginButton));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.pageobject.ocp;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.provider.OpenShiftWebConsoleUrlProvider;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
public class OpenShiftProjectCatalogPage {
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
private final SeleniumWebDriver seleniumWebDriver;
|
||||
private final OpenShiftWebConsoleUrlProvider openShiftWebConsoleUrlProvider;
|
||||
|
||||
protected interface Locators {
|
||||
String TITLE_XPATH = "//h1[contains(text(), 'Browse Catalog')]";
|
||||
String PROJECT_ITEM_XPATH_TEMPLATE =
|
||||
"//div[@id='catalog-projects-summary-list']//a[contains(text(),'%s')]";
|
||||
}
|
||||
|
||||
@FindBy(xpath = Locators.TITLE_XPATH)
|
||||
private WebElement title;
|
||||
|
||||
@Inject
|
||||
public OpenShiftProjectCatalogPage(
|
||||
SeleniumWebDriver seleniumWebDriver,
|
||||
SeleniumWebDriverHelper seleniumWebDriverHelper,
|
||||
OpenShiftWebConsoleUrlProvider openShiftWebConsoleUrlProvider) {
|
||||
this.seleniumWebDriver = seleniumWebDriver;
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
this.openShiftWebConsoleUrlProvider = openShiftWebConsoleUrlProvider;
|
||||
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
public void waitProject(String projectNamePart) {
|
||||
waitOnOpen();
|
||||
String projectItemXpath = String.format(Locators.PROJECT_ITEM_XPATH_TEMPLATE, projectNamePart);
|
||||
seleniumWebDriverHelper.waitVisibility(By.xpath(projectItemXpath));
|
||||
}
|
||||
|
||||
public void waitProjectAbsence(String projectNamePart) {
|
||||
waitOnOpen();
|
||||
String projectItemXpath = String.format(Locators.PROJECT_ITEM_XPATH_TEMPLATE, projectNamePart);
|
||||
seleniumWebDriverHelper.waitInvisibility(By.xpath(projectItemXpath));
|
||||
}
|
||||
|
||||
public void open() {
|
||||
seleniumWebDriver.navigate().to(openShiftWebConsoleUrlProvider.get());
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
String logoutUrl = format("%sconsole/logout", openShiftWebConsoleUrlProvider.get().toString());
|
||||
seleniumWebDriver.navigate().to(logoutUrl);
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
private void waitOnOpen() {
|
||||
seleniumWebDriverHelper.waitVisibility(title);
|
||||
}
|
||||
|
||||
private void waitOnClose() {
|
||||
seleniumWebDriverHelper.waitInvisibility(title);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,66 +11,101 @@
|
|||
package org.eclipse.che.selenium.pageobject.site;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.LoginPageLocators.LOGIN_BUTTON;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.LoginPageLocators.PASSWORD_FIELD;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.LoginPageLocators.USER_NAME_FIELD;
|
||||
import static org.openqa.selenium.support.ui.ExpectedConditions.invisibilityOfElementLocated;
|
||||
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf;
|
||||
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.Locators.LOGIN_BUTTON_NAME;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.Locators.OPEN_SHIFT_OAUTH_LINK_ID;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.Locators.PASSWORD_INPUT_NAME;
|
||||
import static org.eclipse.che.selenium.pageobject.site.CheLoginPage.Locators.USERNAME_INPUT_NAME;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.constant.TestTimeoutsConstants;
|
||||
import org.openqa.selenium.By;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
@Singleton
|
||||
public class CheLoginPage implements LoginPage {
|
||||
private final SeleniumWebDriver seleniumWebDriver;
|
||||
private final WebDriverWait webDriverWait;
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
protected interface LoginPageLocators {
|
||||
String USER_NAME_FIELD = "username";
|
||||
String PASSWORD_FIELD = "password";
|
||||
String LOGIN_BUTTON = "login";
|
||||
private static final String FIRST_NAME = "first name";
|
||||
private static final String LAST_NAME = "last name";
|
||||
|
||||
protected interface Locators {
|
||||
String USERNAME_INPUT_NAME = "username";
|
||||
String PASSWORD_INPUT_NAME = "password";
|
||||
String LOGIN_BUTTON_NAME = "login";
|
||||
String OPEN_SHIFT_OAUTH_LINK_ID = "zocial-openshift-v3";
|
||||
|
||||
String ERROR_ALERT_XPATH = "//div[@class='alert alert-error']/span[@class='kc-feedback-text']";
|
||||
String INFO_ALERT_XPATH = "//div[@class='alert alert-info']/span[@class='kc-feedback-text']";
|
||||
}
|
||||
|
||||
@FindBy(name = USER_NAME_FIELD)
|
||||
@FindBy(name = USERNAME_INPUT_NAME)
|
||||
private WebElement usernameInput;
|
||||
|
||||
@FindBy(name = PASSWORD_FIELD)
|
||||
@FindBy(name = PASSWORD_INPUT_NAME)
|
||||
private WebElement passwordInput;
|
||||
|
||||
@FindBy(name = LOGIN_BUTTON)
|
||||
@FindBy(name = LOGIN_BUTTON_NAME)
|
||||
private WebElement loginButton;
|
||||
|
||||
@Inject
|
||||
public CheLoginPage(SeleniumWebDriver seleniumWebDriver) {
|
||||
this.seleniumWebDriver = seleniumWebDriver;
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
@FindBy(id = OPEN_SHIFT_OAUTH_LINK_ID)
|
||||
private WebElement openShiftOAuthLink;
|
||||
|
||||
webDriverWait = new WebDriverWait(seleniumWebDriver, TestTimeoutsConstants.LOADER_TIMEOUT_SEC);
|
||||
@FindBy(xpath = Locators.INFO_ALERT_XPATH)
|
||||
private WebElement infoAlert;
|
||||
|
||||
@FindBy(xpath = Locators.ERROR_ALERT_XPATH)
|
||||
private WebElement errorAlert;
|
||||
|
||||
@Inject
|
||||
public CheLoginPage(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) {
|
||||
waitOnOpen();
|
||||
|
||||
rewrite(usernameInput, username);
|
||||
seleniumWebDriverHelper.setValue(usernameInput, username);
|
||||
seleniumWebDriverHelper.setValue(passwordInput, password);
|
||||
seleniumWebDriverHelper.waitAndClick(loginButton);
|
||||
|
||||
rewrite(passwordInput, password);
|
||||
|
||||
clickLoginButton();
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
public void loginWithPredefinedUsername(String password) {
|
||||
waitOnOpen();
|
||||
|
||||
seleniumWebDriverHelper.setValue(passwordInput, password);
|
||||
seleniumWebDriverHelper.waitAndClick(loginButton);
|
||||
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetValue(usernameInput);
|
||||
}
|
||||
|
||||
public String getInfoAlert() {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetText(infoAlert);
|
||||
}
|
||||
|
||||
public String getErrorAlert() {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetText(errorAlert);
|
||||
}
|
||||
|
||||
public void loginWithOpenShiftOAuth() {
|
||||
waitOnOpen();
|
||||
seleniumWebDriverHelper.waitAndClick(openShiftOAuthLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpened() {
|
||||
try {
|
||||
|
|
@ -82,30 +117,11 @@ public class CheLoginPage implements LoginPage {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void rewrite(WebElement field, String value) {
|
||||
webDriverWait.until(visibilityOf(field)).clear();
|
||||
waitTextIsPresent(field, "");
|
||||
webDriverWait.until(visibilityOf(field)).sendKeys(value);
|
||||
waitTextIsPresent(field, value);
|
||||
}
|
||||
|
||||
private void clickLoginButton() {
|
||||
webDriverWait.until(visibilityOf(loginButton)).click();
|
||||
}
|
||||
|
||||
private void waitOnOpen() {
|
||||
asList(By.name(USER_NAME_FIELD), By.name(PASSWORD_FIELD), By.name(LOGIN_BUTTON))
|
||||
.forEach(locator -> webDriverWait.until(visibilityOfElementLocated(locator)));
|
||||
seleniumWebDriverHelper.waitAllVisibility(asList(usernameInput, passwordInput, loginButton));
|
||||
}
|
||||
|
||||
private void waitOnClose() {
|
||||
asList(By.name(USER_NAME_FIELD), By.name(PASSWORD_FIELD), By.name(LOGIN_BUTTON))
|
||||
.forEach(locator -> webDriverWait.until(invisibilityOfElementLocated(locator)));
|
||||
}
|
||||
|
||||
private void waitTextIsPresent(WebElement webElement, String expectedText) {
|
||||
webDriverWait.until(
|
||||
(ExpectedCondition<Boolean>)
|
||||
driver -> webElement.getAttribute("value").equals(expectedText));
|
||||
seleniumWebDriverHelper.waitAllInvisibility(asList(usernameInput, passwordInput, loginButton));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.pageobject.site;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
/**
|
||||
* This class describes page where OpenShift user is registering in Che at.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Singleton
|
||||
public class FirstBrokerProfilePage {
|
||||
|
||||
private static final String FIRST_NAME = "first name";
|
||||
private static final String LAST_NAME = "last name";
|
||||
|
||||
private interface Locators {
|
||||
String USERNAME_INPUT_ID = "username";
|
||||
String EMAIL_INPUT_ID = "email";
|
||||
String FIRST_NAME_INPUT_ID = "firstName";
|
||||
String LAST_NAME_INPUT_ID = "lastName";
|
||||
String SUBMIT_BUTTON_XPATH = "//input[@value='Submit']";
|
||||
String ERROR_ALERT_XPATH = "//div[@class='alert alert-error']/span[@class='kc-feedback-text']";
|
||||
String ADD_TO_EXISTING_ACCOUNT_BUTTON_ID = "linkAccount";
|
||||
}
|
||||
|
||||
private SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
@FindBy(id = Locators.USERNAME_INPUT_ID)
|
||||
private WebElement usernameInput;
|
||||
|
||||
@FindBy(id = Locators.EMAIL_INPUT_ID)
|
||||
private WebElement emailInput;
|
||||
|
||||
@FindBy(id = Locators.FIRST_NAME_INPUT_ID)
|
||||
private WebElement firstNameInput;
|
||||
|
||||
@FindBy(id = Locators.LAST_NAME_INPUT_ID)
|
||||
private WebElement lastNameInput;
|
||||
|
||||
@FindBy(xpath = Locators.SUBMIT_BUTTON_XPATH)
|
||||
private WebElement submitButton;
|
||||
|
||||
@FindBy(xpath = Locators.ERROR_ALERT_XPATH)
|
||||
private WebElement errorAlert;
|
||||
|
||||
@FindBy(id = Locators.ADD_TO_EXISTING_ACCOUNT_BUTTON_ID)
|
||||
private WebElement addToExistingAccountButton;
|
||||
|
||||
@Inject
|
||||
public FirstBrokerProfilePage(
|
||||
SeleniumWebDriver seleniumWebDriver, SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
||||
public void submit(TestUser user) {
|
||||
waitOnOpen();
|
||||
|
||||
seleniumWebDriverHelper.setValue(usernameInput, user.getName());
|
||||
seleniumWebDriverHelper.setValue(emailInput, user.getEmail());
|
||||
seleniumWebDriverHelper.setValue(firstNameInput, FIRST_NAME);
|
||||
seleniumWebDriverHelper.setValue(lastNameInput, LAST_NAME);
|
||||
|
||||
seleniumWebDriverHelper.waitAndClick(submitButton);
|
||||
|
||||
waitOnClose();
|
||||
}
|
||||
|
||||
public String getErrorAlert() {
|
||||
return seleniumWebDriverHelper.waitVisibilityAndGetText(errorAlert);
|
||||
}
|
||||
|
||||
public void addToExistingAccount() {
|
||||
seleniumWebDriverHelper.waitAndClick(addToExistingAccountButton);
|
||||
}
|
||||
|
||||
private void waitOnOpen() {
|
||||
seleniumWebDriverHelper.waitAllVisibility(
|
||||
asList(usernameInput, emailInput, lastNameInput, submitButton));
|
||||
}
|
||||
|
||||
private void waitOnClose() {
|
||||
seleniumWebDriverHelper.waitAllInvisibility(
|
||||
asList(usernameInput, emailInput, lastNameInput, submitButton));
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.pageobject;
|
||||
package org.eclipse.che.selenium.pageobject.site;
|
||||
|
||||
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.ELEMENT_TIMEOUT_SEC;
|
||||
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOAD_PAGE_TIMEOUT_SEC;
|
||||
|
|
@ -27,7 +27,7 @@ import org.openqa.selenium.support.ui.WebDriverWait;
|
|||
|
||||
/** @author Andrey Chizhikov */
|
||||
@Singleton
|
||||
public class Profile {
|
||||
public class ProfilePage {
|
||||
|
||||
private interface Locators {
|
||||
String GET_STARTED = "//input[@value='Get Started']";
|
||||
|
|
@ -90,7 +90,7 @@ public class Profile {
|
|||
private final SeleniumWebDriver seleniumWebDriver;
|
||||
|
||||
@Inject
|
||||
public Profile(SeleniumWebDriver seleniumWebDriver) {
|
||||
public ProfilePage(SeleniumWebDriver seleniumWebDriver) {
|
||||
this.seleniumWebDriver = seleniumWebDriver;
|
||||
PageFactory.initElements(seleniumWebDriver, this);
|
||||
}
|
||||
|
|
@ -169,11 +169,11 @@ public class Profile {
|
|||
public void handleProfileOnboardingWithTestData() {
|
||||
if (isGetStartedButtonPresent()) {
|
||||
if (profileFormExists()) {
|
||||
enterValueInField("Test", Profile.Field.FirstName);
|
||||
enterValueInField("Account", Profile.Field.LastName);
|
||||
enterValueInField("AnyCompany", Profile.Field.Company);
|
||||
selectRole(Profile.Role.Developer);
|
||||
selectCountry(Profile.Country.Ukraine);
|
||||
enterValueInField("Test", ProfilePage.Field.FirstName);
|
||||
enterValueInField("Account", ProfilePage.Field.LastName);
|
||||
enterValueInField("AnyCompany", ProfilePage.Field.Company);
|
||||
selectRole(ProfilePage.Role.Developer);
|
||||
selectCountry(ProfilePage.Country.Ukraine);
|
||||
clickOnGetStarted();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.site.ocpoauth;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack.JAVA;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.api.core.model.workspace.Workspace;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.TestGroup;
|
||||
import org.eclipse.che.selenium.core.client.TestWorkspaceServiceClient;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.eclipse.che.selenium.pageobject.Ide;
|
||||
import org.eclipse.che.selenium.pageobject.ToastLoader;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.AuthorizeOpenShiftAccessPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftProjectCatalogPage;
|
||||
import org.eclipse.che.selenium.pageobject.site.CheLoginPage;
|
||||
import org.eclipse.che.selenium.pageobject.site.FirstBrokerProfilePage;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* This test checks if existed user of Eclipse Che Multiuser deployed on OCP can log into Eclipse
|
||||
* Che by using OCP OAuth server identity provider and work with workspace as own OCP resource.<br>
|
||||
* <br>
|
||||
* <b>Test environment</b>: <br>
|
||||
* Eclipse Che Multiuser deployed on OCP with support of OpenShift OAuth server.<br>
|
||||
* If you are going to deploy Eclipse Che on OCP with {@code deploy/openshift/ocp.sh} script, use
|
||||
* {@code --setup-ocp-oauth} parameter to setup OCP OAuth identity provider.<br>
|
||||
* <br>
|
||||
* <b>Test case</b>:<br>
|
||||
* - register new Eclipse Che user;<br>
|
||||
* - go to login page of Eclipse Che;<br>
|
||||
* - click on button to login with OpenShift OAuth;<br>
|
||||
* - login to OCP with registered earlier Eclipse Che test user credentials;<br>
|
||||
* - authorize ocp-client to access OpenShift account;<br>
|
||||
* - fill first broker profile page;<br>
|
||||
* - add OCP user to existed Che user account;<br>
|
||||
* - login into Eclipse Che again;<br>
|
||||
* - create and open workspace of java type;<br>
|
||||
* - switch to the Eclipse Che IDE and wait until workspace is ready to use;<br>
|
||||
* - go to OCP and check there if there is a project with name equals to test workspace id;<br>
|
||||
* - remove test workspace from Eclipse Che Dashboard;<br>
|
||||
* - go to OCP and check there if there is no project with name equals to test workspace id.<br>
|
||||
* <br>
|
||||
* <a href="https://github.com/eclipse/che/issues/8178">Feature reference.</a> <br>
|
||||
* <br>
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Test(groups = {TestGroup.OPENSHIFT, TestGroup.MULTIUSER})
|
||||
public class LoginExistedUserWithOpenShiftOAuthTest {
|
||||
|
||||
private static final String WORKSPACE_NAME = NameGenerator.generate("workspace", 4);
|
||||
|
||||
public static final String LOGIN_TO_CHE_WITH_OPENSHIFT_OAUTH_MESSAGE_TEMPLATE =
|
||||
"Authenticate as %s to link your account with openshift-v3";
|
||||
|
||||
public static final String USER_ALREADY_EXISTS_ERROR_MESSAGE_TEMPLATE =
|
||||
"User with email %s already exists. How do you want to continue?";
|
||||
|
||||
@Inject private CheLoginPage cheLoginPage;
|
||||
@Inject private OpenShiftLoginPage openShiftLoginPage;
|
||||
@Inject private FirstBrokerProfilePage firstBrokerProfilePage;
|
||||
@Inject private AuthorizeOpenShiftAccessPage authorizeOpenShiftAccessPage;
|
||||
@Inject private DefaultTestUser defaultTestUser;
|
||||
@Inject private Dashboard dashboard;
|
||||
@Inject private Workspaces workspaces;
|
||||
@Inject private NewWorkspace newWorkspace;
|
||||
@Inject private TestWorkspaceServiceClient defaultUserWorkspaceServiceClient;
|
||||
@Inject private ToastLoader toastLoader;
|
||||
@Inject private Ide ide;
|
||||
@Inject private SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
@Inject private OpenShiftProjectCatalogPage openShiftProjectCatalogPage;
|
||||
@Inject private SeleniumWebDriver seleniumWebDriver;
|
||||
@Inject private TestDashboardUrlProvider testDashboardUrlProvider;
|
||||
|
||||
@AfterClass
|
||||
private void removeTestWorkspace() throws Exception {
|
||||
defaultUserWorkspaceServiceClient.delete(WORKSPACE_NAME, defaultTestUser.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkExistedCheUserOcpProjectCreationAndRemoval() throws Exception {
|
||||
// go to login page of Eclipse Che
|
||||
// (we can't use dashboard.open() here to login with OAuth)
|
||||
seleniumWebDriver.navigate().to(testDashboardUrlProvider.get());
|
||||
|
||||
// click on button to login with OpenShift OAuth
|
||||
cheLoginPage.loginWithOpenShiftOAuth();
|
||||
|
||||
// login to OCP from login page with default test user credentials
|
||||
openShiftLoginPage.login(defaultTestUser.getName(), defaultTestUser.getPassword());
|
||||
|
||||
// authorize ocp-client to access OpenShift account
|
||||
authorizeOpenShiftAccessPage.waitOnOpen();
|
||||
authorizeOpenShiftAccessPage.allowPermissions();
|
||||
|
||||
// fill first broker profile page
|
||||
firstBrokerProfilePage.submit(defaultTestUser);
|
||||
|
||||
// add OCP user to existed Eclipse Che user account
|
||||
String expectedError =
|
||||
format(USER_ALREADY_EXISTS_ERROR_MESSAGE_TEMPLATE, defaultTestUser.getEmail());
|
||||
|
||||
assertEquals(firstBrokerProfilePage.getErrorAlert(), expectedError);
|
||||
firstBrokerProfilePage.addToExistingAccount();
|
||||
|
||||
// login into Eclipse Che again
|
||||
String expectedInfo =
|
||||
format(LOGIN_TO_CHE_WITH_OPENSHIFT_OAUTH_MESSAGE_TEMPLATE, defaultTestUser.getName());
|
||||
assertEquals(cheLoginPage.getInfoAlert(), expectedInfo);
|
||||
cheLoginPage.loginWithPredefinedUsername(defaultTestUser.getPassword());
|
||||
|
||||
// create and open workspace of java type
|
||||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.clickOnAllStacksTab();
|
||||
newWorkspace.selectStack(JAVA);
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE_NAME);
|
||||
newWorkspace.clickOnCreateButtonAndOpenInIDE();
|
||||
|
||||
// switch to the Eclipse Che IDE and wait until workspace is ready to use
|
||||
seleniumWebDriverHelper.switchToIdeFrameAndWaitAvailability();
|
||||
toastLoader.waitToastLoaderAndClickStartButton();
|
||||
ide.waitOpenedWorkspaceIsReadyToUse();
|
||||
|
||||
// go to OCP and check if there is a project with name equals to test workspace id
|
||||
openShiftProjectCatalogPage.open();
|
||||
openShiftLoginPage.login(defaultTestUser.getName(), defaultTestUser.getPassword());
|
||||
Workspace testWorkspace =
|
||||
defaultUserWorkspaceServiceClient.getByName(WORKSPACE_NAME, defaultTestUser.getName());
|
||||
openShiftProjectCatalogPage.waitProject(testWorkspace.getId());
|
||||
|
||||
// remove test workspace from Eclipse Che Dashboard
|
||||
seleniumWebDriver.navigate().to(testDashboardUrlProvider.get());
|
||||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.selectAllWorkspacesByBulk();
|
||||
workspaces.clickOnDeleteWorkspacesBtn();
|
||||
workspaces.clickOnDeleteButtonInDialogWindow();
|
||||
workspaces.waitWorkspaceIsNotPresent(WORKSPACE_NAME);
|
||||
|
||||
// go to OCP and check if there is no project with name equals to test workspace id
|
||||
openShiftProjectCatalogPage.open();
|
||||
openShiftProjectCatalogPage.waitProjectAbsence(testWorkspace.getId());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.site.ocpoauth;
|
||||
|
||||
import static org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace.Stack.JAVA;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.TestGroup;
|
||||
import org.eclipse.che.selenium.core.client.TestUserServiceClient;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.eclipse.che.selenium.pageobject.Ide;
|
||||
import org.eclipse.che.selenium.pageobject.ToastLoader;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.Dashboard;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.NewWorkspace;
|
||||
import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.AuthorizeOpenShiftAccessPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftLoginPage;
|
||||
import org.eclipse.che.selenium.pageobject.ocp.OpenShiftProjectCatalogPage;
|
||||
import org.eclipse.che.selenium.pageobject.site.CheLoginPage;
|
||||
import org.eclipse.che.selenium.pageobject.site.FirstBrokerProfilePage;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* This test checks user can be registered in Eclipse Che Multiuser deployed on OCP with OCP OAuth
|
||||
* server identity provider and work with workspace as own OCP resource.<br>
|
||||
* <br>
|
||||
* <b>Test environment</b>: <br>
|
||||
* Eclipse Che Multiuser deployed on OCP with support of OpenShift OAuth server.<br>
|
||||
* If you are going to deploy Eclipse Che on OCP with {@code deploy/openshift/ocp.sh} script, use
|
||||
* {@code --setup-ocp-oauth} parameter to setup OCP OAuth identity provider.<br>
|
||||
* <br>
|
||||
* <b>Test case</b>:<br>
|
||||
* - go to login page of Eclipse Che;<br>
|
||||
* - click on button to login with OpenShift OAuth;<br>
|
||||
* - login to OCP with new Eclipse Che test user credentials;<br>
|
||||
* - authorize ocp-client to access OpenShift account;<br>
|
||||
* - fill first broker profile page;<br>
|
||||
* - create and open workspace of java type;<br>
|
||||
* - switch to the Eclipse Che IDE and wait until workspace is ready to use;<br>
|
||||
* - go to OCP and check there if there is a project with name starts from "workspace";<br>
|
||||
* - remove test workspace from Eclipse Che Dashboard;<br>
|
||||
* - go to OCP and check there if there is no project with name starts from "workspace".<br>
|
||||
* <br>
|
||||
* <a href="https://github.com/eclipse/che/issues/8178">Feature reference.</a> <br>
|
||||
* <br>
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Test(groups = {TestGroup.OPENSHIFT, TestGroup.MULTIUSER})
|
||||
public class LoginNewUserWithOpenShiftOAuthTest {
|
||||
|
||||
private static final String WORKSPACE_NAME = NameGenerator.generate("workspace", 4);
|
||||
private static final String WORKSPACE_ID_PREFIX = "workspace";
|
||||
|
||||
private static final TestUser NEW_TEST_USER = getTestUser();
|
||||
|
||||
@Inject private CheLoginPage cheLoginPage;
|
||||
@Inject private OpenShiftLoginPage openShiftLoginPage;
|
||||
@Inject private FirstBrokerProfilePage firstBrokerProfilePage;
|
||||
@Inject private AuthorizeOpenShiftAccessPage authorizeOpenShiftAccessPage;
|
||||
@Inject private Dashboard dashboard;
|
||||
@Inject private Workspaces workspaces;
|
||||
@Inject private NewWorkspace newWorkspace;
|
||||
@Inject private ToastLoader toastLoader;
|
||||
@Inject private Ide ide;
|
||||
@Inject private SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
@Inject private TestUserServiceClient testUserServiceClient;
|
||||
@Inject private OpenShiftProjectCatalogPage openShiftProjectCatalogPage;
|
||||
@Inject private SeleniumWebDriver seleniumWebDriver;
|
||||
@Inject private TestDashboardUrlProvider testDashboardUrlProvider;
|
||||
|
||||
@AfterClass
|
||||
private void removeTestUser() throws ServerException, ConflictException, BadRequestException {
|
||||
try {
|
||||
User newTestUserDto = testUserServiceClient.findByName(NEW_TEST_USER.getName());
|
||||
testUserServiceClient.remove(newTestUserDto.getId());
|
||||
} catch (NotFoundException e) {
|
||||
// ignore if test user don't exist
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkNewCheUserOcpProjectCreationAndRemoval() {
|
||||
// go to login page of Eclipse Che
|
||||
// (we can't use dashboard.open() here to login with OAuth)
|
||||
seleniumWebDriver.navigate().to(testDashboardUrlProvider.get());
|
||||
|
||||
// click on button to login with OpenShift OAuth
|
||||
cheLoginPage.loginWithOpenShiftOAuth();
|
||||
|
||||
// login to OCP from login page with new test user credentials
|
||||
openShiftLoginPage.login(NEW_TEST_USER.getName(), NEW_TEST_USER.getPassword());
|
||||
|
||||
// authorize ocp-client to access OpenShift account
|
||||
authorizeOpenShiftAccessPage.waitOnOpen();
|
||||
authorizeOpenShiftAccessPage.allowPermissions();
|
||||
|
||||
// fill first broker profile page
|
||||
firstBrokerProfilePage.submit(NEW_TEST_USER);
|
||||
|
||||
// create and open workspace of java type
|
||||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.clickOnAddWorkspaceBtn();
|
||||
newWorkspace.waitToolbar();
|
||||
newWorkspace.clickOnAllStacksTab();
|
||||
newWorkspace.selectStack(JAVA);
|
||||
newWorkspace.typeWorkspaceName(WORKSPACE_NAME);
|
||||
newWorkspace.clickOnCreateButtonAndOpenInIDE();
|
||||
|
||||
// switch to the Eclipse Che IDE and wait until workspace is ready to use
|
||||
seleniumWebDriverHelper.switchToIdeFrameAndWaitAvailability();
|
||||
toastLoader.waitToastLoaderAndClickStartButton();
|
||||
ide.waitOpenedWorkspaceIsReadyToUse();
|
||||
|
||||
// go to OCP and check if there is a project with name starts from "workspace"
|
||||
openShiftProjectCatalogPage.open();
|
||||
openShiftLoginPage.login(NEW_TEST_USER.getName(), NEW_TEST_USER.getPassword());
|
||||
openShiftProjectCatalogPage.waitProject(WORKSPACE_ID_PREFIX);
|
||||
|
||||
// remove test workspace from Eclipse Che Dashboard
|
||||
seleniumWebDriver.navigate().to(testDashboardUrlProvider.get());
|
||||
dashboard.selectWorkspacesItemOnDashboard();
|
||||
workspaces.selectAllWorkspacesByBulk();
|
||||
workspaces.clickOnDeleteWorkspacesBtn();
|
||||
workspaces.clickOnDeleteButtonInDialogWindow();
|
||||
workspaces.waitWorkspaceIsNotPresent(WORKSPACE_NAME);
|
||||
|
||||
// go to OCP and check if there is no project with name starts from "workspace"
|
||||
openShiftProjectCatalogPage.open();
|
||||
openShiftProjectCatalogPage.waitProjectAbsence(WORKSPACE_ID_PREFIX);
|
||||
}
|
||||
|
||||
private static TestUser getTestUser() {
|
||||
return new TestUser() {
|
||||
private final long currentTimeInMillisec = System.currentTimeMillis();
|
||||
private final String name = "user" + currentTimeInMillisec;
|
||||
private final String email = name + "@1.com";
|
||||
private final String password = String.valueOf(currentTimeInMillisec);
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String obtainAuthToken() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOfflineToken() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {}
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue