/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.selenium;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.UUID;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.InitialPage;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.olat.restapi.support.vo.CourseVO;
import org.olat.selenium.page.LoginPage;
import org.olat.selenium.page.NavigationPage;
import org.olat.selenium.page.Student;
import org.olat.selenium.page.User;
import org.olat.selenium.page.course.CoursePageFragment;
import org.olat.selenium.page.graphene.OOGraphene;
import org.olat.selenium.page.group.GroupsPage;
import org.olat.selenium.page.repository.AuthoringEnvPage;
import org.olat.selenium.page.user.ImportUserPage;
import org.olat.selenium.page.user.PortalPage;
import org.olat.selenium.page.user.UserAdminPage;
import org.olat.selenium.page.user.UserPasswordPage;
import org.olat.selenium.page.user.UserPreferencesPageFragment;
import org.olat.selenium.page.user.UserPreferencesPageFragment.ResumeOption;
import org.olat.selenium.page.user.UserProfilePage;
import org.olat.selenium.page.user.UserToolsPage;
import org.olat.selenium.page.user.VisitingCardPage;
import org.olat.test.ArquillianDeployments;
import org.olat.test.rest.RepositoryRestClient;
import org.olat.test.rest.UserRestClient;
import org.olat.user.restapi.UserVO;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
/**
*
* Initial date: 19.06.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@RunWith(Arquillian.class)
public class UserTest {
@Deployment(testable = false)
public static WebArchive createDeployment() {
return ArquillianDeployments.createDeployment();
}
@Drone
private WebDriver browser;
@ArquillianResource
private URL deploymentUrl;
@Page
private NavigationPage navBar;
/**
* Set the resume preferences to automatically resume the session,
* open a course, log out, log in and check if the course is resumed.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void resumeCourseAutomatically(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//create a random user
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
//deploy a course
CourseVO course = new RepositoryRestClient(deploymentUrl).deployDemoCourse();
//login
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
//set the preferences to resume automatically
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openMySettings()
.assertOnUserSettings()
.openPreferences()
.assertOnUserPreferences()
.setResume(ResumeOption.auto);
//open a course via REST url
CoursePageFragment coursePage = CoursePageFragment.getCourse(browser, deploymentUrl, course);
coursePage
.assertOnCoursePage()
.clickTree();
//logout
userTools.logout();
//login again
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
//check the title of the course if any
WebElement courseTitle = browser.findElement(By.tagName("h2"));
Assert.assertNotNull(courseTitle);
Assert.assertTrue(courseTitle.isDisplayed());
Assert.assertTrue(courseTitle.getText().contains(course.getTitle()));
}
/**
* Set the resume preferences to resume the session on request,
* open a course, log out, log in, resume the session and check
* if the course is resumed.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void resumeCourseOnDemand(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//create a random user
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
//deploy a course
CourseVO course = new RepositoryRestClient(deploymentUrl).deployDemoCourse();
//login
loginPage.loginAs(user.getLogin(), user.getPassword());
//set the preferences to resume automatically
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openMySettings()
.openPreferences()
.setResume(ResumeOption.ondemand);
//open a course via REST url and click it
CoursePageFragment.getCourse(browser, deploymentUrl, course).clickTree();
//logout
userTools.logout();
//login again
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
//resume
loginPage.resumeWithAssert();
//check the title of the course if any
WebElement courseTitle = browser.findElement(By.tagName("h2"));
Assert.assertNotNull(courseTitle);
Assert.assertTrue(courseTitle.isDisplayed());
Assert.assertTrue(courseTitle.getText().contains(course.getTitle()));
}
/**
* Disable the resume function and check that the resume
* popup don't stay in our way after login.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void resumeDisabled(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
//set the preferences to resume automatically
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openMySettings()
.openPreferences()
.setResume(ResumeOption.none);
//logout
userTools.logout();
//login again
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
//check that we don't see the resume button
List<WebElement> resumeButtons = browser.findElements(LoginPage.resumeButton);
Assert.assertTrue(resumeButtons.isEmpty());
//double check that we are really logged in
loginPage.assertLoggedIn(user);
}
/**
* An user configures its landing page, log out
* and try it.
*
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void loginInHomeWithLandingPage(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//create a random user
UserRestClient userClient = new UserRestClient(deploymentUrl);
UserVO user = userClient.createAuthor();
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openMySettings()
.openPreferences()
.setResume(ResumeOption.none)
.setLandingPage("/RepositorySite/0/Search/0");
userTools.logout();
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
new AuthoringEnvPage(browser)
.assertOnGenericSearch();
}
/**
* Jump to notifications in home, go to the courses and return
* to home's notification with a REST url.
*
* @see https://jira.openolat.org/browse/OO-1962
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void loginInHomeWithRestUrl(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//create a random user
UserRestClient userClient = new UserRestClient(deploymentUrl);
UserVO user = userClient.createRandomUser();
//load dmz
loginPage.assertOnLoginPage();
String jumpToNotificationsUrl = deploymentUrl.toString() + "url/HomeSite/" + user.getKey() + "/notifications/0";
browser.get(jumpToNotificationsUrl);
loginPage.loginAs(user.getLogin(), user.getPassword());
//must see the notification
new UserToolsPage(browser).assertOnNotifications();
//go to courses
navBar.openMyCourses();
//use url to go to notifications
String goToNotificationsUrl = deploymentUrl.toString() + "auth/HomeSite/" + user.getKey() + "/notifications/0";
browser.get(goToNotificationsUrl);
//must see the notification
new UserToolsPage(browser).assertOnNotifications();
}
/**
* Check if a user can use the rest url in OpenOLAT.
* It jump from the static sites to its home, user tools,
* to the visiting card of an other user.
*
* @param loginPage
* @param authorBrowser
* @param participantBrowser
* @param reiBrowser
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void restUrlAfterLogin(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//create a random user
UserRestClient userClient = new UserRestClient(deploymentUrl);
UserVO user = userClient.createRandomUser("Kanu");
UserVO ryomou = userClient.createRandomUser("Ryomou");
//load dmz
loginPage
.assertOnLoginPage()
.loginAs(user.getLogin(), user.getPassword());
//go to courses
navBar.openMyCourses();
//use url to go to the other users business card
String ryomouBusinessCardUrl = deploymentUrl.toString() + "auth/Identity/" + ryomou.getKey();
browser.get(ryomouBusinessCardUrl);
new VisitingCardPage(browser)
.assertOnVisitingCard()
.assertOnLastName(ryomou.getLastName());
//return to my courses
navBar.openMyCourses()
.assertOnMyCourses();
//go to profile by url
String userUrl = deploymentUrl.toString() + "url/Identity/" + user.getKey();
browser.get(userUrl);
new UserProfilePage(browser)
.assertOnProfile()
.assertOnUsername(user.getLogin());
//go to groups
String groupsUrl = deploymentUrl.toString() + "url/GroupsSite/0/AllGroups/0";
browser.get(groupsUrl);
new GroupsPage(browser)
.assertOnMyGroupsSelected();
//go to my calendar
String calendarUrl = deploymentUrl.toString() + "auth/HomeSite/0/calendar/0";
browser.get(calendarUrl);
new UserToolsPage(browser)
.assertOnCalendar();
//go to my folder
String folderUrl = deploymentUrl.toString() + "auth/HomeSite/" + user.getKey() + "/userfolder/0";
browser.get(folderUrl);
new UserToolsPage(browser)
.assertOnFolder();
}
/**
* Switch the language to german and after logout login to english
* and check every time.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void userSwitchLanguageSwitchToEnglish(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
//set the languages preferences to german
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openMySettings()
.assertOnUserSettings()
.openPreferences()
.assertOnUserPreferences()
.setLanguage("de");
userTools.logout();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
WebElement usernameDE = browser.findElement(LoginPage.usernameFooterBy);
boolean de = usernameDE.getText().contains("Eingeloggt als");
Assert.assertTrue(de);
List<WebElement> deMarker = browser.findElements(By.className("o_lang_de"));
Assert.assertFalse(deMarker.isEmpty());
//set the languages preferences to english
userTools
.openUserToolsMenu()
.openMySettings()
.openPreferences()
.setLanguage("en");
userTools.logout();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
WebElement usernameEN = browser.findElement(LoginPage.usernameFooterBy);
boolean en = usernameEN.getText().contains("Logged in as");
Assert.assertTrue(en);
List<WebElement> enMarker = browser.findElements(By.className("o_lang_en"));
Assert.assertFalse(enMarker.isEmpty());
}
/**
* Change the password, log out and try to log in again
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void userChangeItsPassword(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
UserToolsPage userTools = new UserToolsPage(browser);
userTools
.openUserToolsMenu()
.openPassword();
String newPassword = UUID.randomUUID().toString();
UserPasswordPage password = UserPasswordPage.getUserPasswordPage(browser);
password.setNewPassword(user.getPassword(), newPassword);
userTools.logout();
loginPage
.loginAs(user.getLogin(), newPassword)
.resume()
.assertLoggedIn(user);
}
/**
* Reset the preferences and check that a log out happens
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void userResetItsPreferences(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword())
.resume();
UserToolsPage userTools = new UserToolsPage(browser);
UserPreferencesPageFragment prefs = userTools
.openUserToolsMenu()
.openMySettings()
.openPreferences();
//reset the preferences
prefs.resetPreferences();
//check the user is log out
loginPage.assertOnLoginPage();
}
/**
* Go in portal, edit it, deactivate the quick start portlet,
* finish editing, check that the quick start portlet disappears,
* re-edit, reactivate the quick start portlet and check it is
* again in the non-edit view.
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void portletDeactivateActivate(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword());
PortalPage portal = navBar.openPortal()
.assertPortlet(PortalPage.quickStartBy)
.edit()
.disable(PortalPage.quickStartBy)
.finishEditing()
.assertNotPortlet(PortalPage.quickStartBy);
//re-enable quickstart
portal.edit()
.enable(PortalPage.quickStartBy)
.finishEditing()
.assertPortlet(PortalPage.quickStartBy);
List<WebElement> portalInactive = browser.findElements(PortalPage.inactiveBy);
Assert.assertTrue(portalInactive.isEmpty());
}
/**
* Go to the portal, edit it, move the notes to the
* top, quit editing, check the notes are the first
* portlet in the view mode.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void movePortletToTheTop(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO user = new UserRestClient(deploymentUrl).createRandomUser();
loginPage
.loginAs(user.getLogin(), user.getPassword());
PortalPage portal = navBar.openPortal()
.assertPortlet(PortalPage.notesBy)
.edit()
.moveLeft(PortalPage.notesBy)
.moveUp(PortalPage.notesBy)
.moveUp(PortalPage.notesBy)
.moveUp(PortalPage.notesBy)
.moveRight(PortalPage.quickStartBy)
.moveDown(PortalPage.quickStartBy);
//finish editing
portal.finishEditing();
//no inactive panel -> we are in view mode
List<WebElement> portalInactive = browser.findElements(PortalPage.inactiveBy);
Assert.assertTrue(portalInactive.isEmpty());
//notes must be first
List<WebElement> portlets = browser.findElements(By.className("o_portlet"));
Assert.assertFalse(portlets.isEmpty());
WebElement notesPortlet = portlets.get(0);
String cssClass = notesPortlet.getAttribute("class");
Assert.assertNotNull(cssClass);
Assert.assertTrue(cssClass.contains("o_portlet_notes"));
}
/**
* Browse some tabs, two times back and check where I am.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void browserBack(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
loginPage
.loginAs("administrator", "openolat")
.resume();
navBar
.openPortal()
.assertPortlet(PortalPage.quickStartBy);
navBar.openAuthoringEnvironment();
navBar.openGroups(browser);
navBar.openMyCourses();
navBar.openUserManagement();
navBar.openAdministration();
//we are in administration
browser.navigate().back();
//we are in user management
browser.navigate().back();
//we are in "My courses", check
OOGraphene.waitElement(NavigationPage.myCoursesAssertBy, browser);
}
/**
* The administrator create an user, the user log in.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void createUser(@InitialPage LoginPage loginPage,
@Drone @User WebDriver userBrowser)
throws IOException, URISyntaxException {
//login
loginPage
.assertOnLoginPage()
.loginAs("administrator", "openolat")
.resume();
String uuid = UUID.randomUUID().toString();
String username = "miku-" + uuid;
UserVO userVo = UserAdminPage.createUserVO(username, "Miku", "Hatsune", "miku-" + uuid + "@openolat.com", "miku01");
UserAdminPage userAdminPage = navBar
.openUserManagement()
.openCreateUser()
.fillUserForm(userVo)
.assertOnUserEditView(username);
userAdminPage
.openSearchUser()
.searchByUsername(username)
.assertOnUserInList(username)
.selectByUsername(username)
.assertOnUserEditView(username);
//user log in
LoginPage userLoginPage = LoginPage.getLoginPage(userBrowser, deploymentUrl);
//tools
userLoginPage
.loginAs(username, "miku01")
.resume()
.assertLoggedIn(userVo);
}
/**
* Test if deleted user cannot login anymore. An administrator
* create a user. This user log in and log out. The administrator
* use the direct delete workflow in user management to delete
* it.<br>
* The user try to log in again, unsuccessfully. The
* administrator doesn't find it anymore in the user
* search of the user management tab.
*
*/
@Test
@RunAsClient
public void deleteUser(@InitialPage LoginPage loginPage,
@Drone @User WebDriver userBrowser) {
//login
loginPage
.assertOnLoginPage()
.loginAs("administrator", "openolat")
.resume();
String uuid = UUID.randomUUID().toString();
String username = "miku-" + uuid;
String lastName = "Hatsune" + uuid;
UserVO userVo = UserAdminPage.createUserVO(username, "Miku", lastName, "miku-" + uuid + "@openolat.com", "miku01");
UserAdminPage userAdminPage = navBar
.openUserManagement()
.openCreateUser()
.fillUserForm(userVo)
.assertOnUserEditView(username);
//user log in
LoginPage userLoginPage = LoginPage.getLoginPage(userBrowser, deploymentUrl);
//tools
userLoginPage
.loginAs(username, "miku01")
.resume()
.assertLoggedIn(userVo);
//log out
new UserToolsPage(userBrowser).logout();
//admin delete
userAdminPage
.openDirectDeleteUser()
.searchUserToDelete(username)
.selectAndDeleteUser(lastName);
//user try the login
userLoginPage = LoginPage.getLoginPage(userBrowser, deploymentUrl);
userLoginPage
.loginDenied(username, "miku01");
//assert on error message
By errorMessageby = By.cssSelector("div.modal-body.alert.alert-danger");
OOGraphene.waitElement(errorMessageby, 2, userBrowser);
// administrator search the deleted user
userAdminPage
.openSearchUser()
.searchByUsername(username)
.assertNotInUserList(username);
}
/**
* Import 2 new users and check if the first can log in.
*
* @param loginPage
* @param userBrowser
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void importUsers(@InitialPage LoginPage loginPage,
@Drone @User WebDriver userBrowser)
throws IOException, URISyntaxException {
//login
loginPage
.assertOnLoginPage()
.loginAs("administrator", "openolat")
.resume();
UserAdminPage userAdminPage = navBar
.openUserManagement()
.openImportUsers();
//start import wizard
ImportUserPage importWizard = userAdminPage.startImport();
String uuid = UUID.randomUUID().toString();
String username1 = "moka-" + uuid;
String username2 = "mizore-" + uuid;
StringBuilder csv = new StringBuilder();
UserVO user1 = importWizard.append(username1, "rosario01", "Moka", "Akashiya", csv);
importWizard.append(username2, "vampire01", "Mizore", "Shirayuki", csv);
importWizard
.fill(csv.toString())
.next() // -> preview
.assertGreen(2)
.next() // -> groups
.next() // -> emails
.finish();
OOGraphene.waitAndCloseBlueMessageWindow(browser);
//user log in
LoginPage userLoginPage = LoginPage.getLoginPage(userBrowser, deploymentUrl);
//tools
userLoginPage
.loginAs(username1, "rosario01")
.resume()
.assertLoggedIn(user1);
}
/**
* Import 1 new user and 1 existing, change the password and the last name
* of the existing user.
*
* @param loginPage
* @param existingUserBrowser
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void importExistingUsers(@InitialPage LoginPage loginPage,
@Drone @User WebDriver existingUserBrowser,
@Drone @Student WebDriver newUserBrowser)
throws IOException, URISyntaxException {
UserVO user1 = new UserRestClient(deploymentUrl)
.createRandomUser("tsukune");
//login
loginPage
.assertOnLoginPage()
.loginAs("administrator", "openolat")
.resume();
UserAdminPage userAdminPage = navBar
.openUserManagement()
.openImportUsers();
//start import wizard
ImportUserPage importWizard = userAdminPage.startImport();
String uuid = UUID.randomUUID().toString();
String username1 = "moka-" + uuid;
StringBuilder csv = new StringBuilder();
UserVO newUser = importWizard.append(username1, "rosario02", "Moka", "Akashiya", csv);
user1 = importWizard.append(user1, "Aono", "openolat2", csv);
importWizard
.fill(csv.toString())
.next() // -> preview
.assertGreen(1)
.assertWarn(1)
.updatePasswords()
.updateUsers()
.next() // -> groups
.next() // -> emails
.finish();
OOGraphene.waitAndCloseBlueMessageWindow(browser);
//existing user log in with its new password and check if its name was updated
LoginPage userLoginPage = LoginPage.getLoginPage(existingUserBrowser, deploymentUrl);
//tools
userLoginPage
.loginAs(user1.getLogin(), "openolat2")
.resume()
.assertLoggedInByLastName("Aono");
//new user log in
LoginPage newLoginPage = LoginPage.getLoginPage(newUserBrowser, deploymentUrl);
//tools
newLoginPage
.loginAs(newUser.getLogin(), "rosario02")
.resume()
.assertLoggedInByLastName("Akashiya");
}
}