Skip to content
Snippets Groups Projects
Commit a08a8140 authored by srosse's avatar srosse
Browse files

OO-1068: 2 selenium test for the portfolio (file artefacts)

parent 9a8220bd
No related branches found
No related tags found
No related merge requests found
/**
* <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.portfolio;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
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.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.olat.modules.fo.portfolio.ForumArtefact;
import org.olat.modules.wiki.portfolio.WikiArtefact;
import org.olat.portfolio.FunctionalArtefactTest.Binder.Page;
import org.olat.portfolio.FunctionalArtefactTest.Binder.Page.Artefact;
import org.olat.portfolio.FunctionalArtefactTest.Binder.Page.BlogArtefact;
import org.olat.portfolio.FunctionalArtefactTest.Binder.Page.JournalArtefact;
import org.olat.portfolio.FunctionalArtefactTest.Binder.Page.TextArtefact;
import org.olat.portfolio.model.artefacts.FileArtefact;
import org.olat.test.ArquillianDeployments;
import org.olat.user.restapi.UserVO;
import org.olat.util.FunctionalCourseUtil;
import org.olat.util.FunctionalEPortfolioUtil;
import org.olat.util.FunctionalEPortfolioUtil.ArtefactAlias;
import org.olat.util.FunctionalHomeSiteUtil;
import org.olat.util.FunctionalRepositorySiteUtil;
import org.olat.util.FunctionalUtil;
import org.olat.util.FunctionalUtil.WaitLimitAttribute;
import org.olat.util.FunctionalVOUtil;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
/**
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
@RunWith(Arquillian.class)
public class FunctionalArtefactTest {
/* content */
public final static String BINDER_PROGRAMMING_THEORIE = "programming (theorie)";
public final static String BINDER_PROGRAMMING_SAMPLES = "programming (code samples)";
public final static String FORUM_POST_TITLE = "question about multiplexing";
public final static String FORUM_POST_MESSAGE = "What multiplexing exists in operating systems?";
public final static String FORUM_ARTEFACT_TITLE = "multiplexing forum post";
public final static String FORUM_ARTEFACT_DESCRIPTION = "Thread about multiplexing.";
public final static String[] FORUM_TAGS = {"networking", "multiplexing", "operating systems", "virtual machine", "forum", "post"};
public final static String FORUM_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String FORUM_PAGE = "operating systems";
public final static String FORUM_STRUCTURE = "issue 1";
public final static String WIKI_ARTICLE_PAGENAME = "Multiplexing";
public final static String WIKI_ARTICLE_CONTENT = "==Time Multiplexing==\nscheduling a serially-reusable resource among several users\n\n==Space multiplexing==\ndividing a multiple-use resource up among several users";
public final static String WIKI_ARTEFACT_TITLE = "multiplexing wiki";
public final static String WIKI_ARTEFACT_DESCRIPTION = "wiki page about multiplexing";
public final static String[] WIKI_TAGS = {"networking", "multiplexing", "operating systems", "virtual machine", "wiki"};
public final static String WIKI_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String WIKI_PAGE = "operating systems";
public final static String WIKI_STRUCTURE = "issue 2";
public final static String BLOG_TITLE = "My Blog";
public final static String BLOG_DESCRIPTION = "Blog created with Selenium";
public final static String BLOG_POST_TITLE = "Multiplexing articles";
public final static String BLOG_POST_DESCRIPTION = "Where you may find useful information about multiplexing.";
public final static String BLOG_POST_CONTENT = "Operating Systems: Design and Implementation (by Andrew S. Tanenbaum)";
public final static String BLOG_ARTEFACT_TITLE = "blog";
public final static String BLOG_ARTEFACT_DESCRIPTION = "my personal blog";
public final static String[] BLOG_TAGS = {"john smith", "blog"};
public final static String BLOG_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String BLOG_PAGE = "operating systems";
public final static String BLOG_STRUCTURE = "issue 3";
public final static String TEXT_ARTEFACT_CONTENT = "Bufferbloat is a phenomenon in a packet-switched computer network whereby excess buffering of packets inside the network causes high latency and jitter, as well as reducing the overall network throughput.";
public final static String TEXT_ARTEFACT_TITLE = "Definition bufferbloat";
public final static String TEXT_ARTEFACT_DESCRIPTION = "Definition bufferbloat";
public final static String[] TEXT_ARTEFACT_TAGS = {"bufferbloat", "network", "latency", "jitter"};
public final static String TEXT_ARTEFACT_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String TEXT_ARTEFACT_PAGE = "networking";
public final static String TEXT_ARTEFACT_STRUCTURE = "issue 1";
public final static String FILE_ARTEFACT_PATH = "/org/olat/portfolio/sfqcodel.cc";
public final static String FILE_ARTEFACT_TITLE = "CoDel";
public final static String FILE_ARTEFACT_DESCRIPTION = "CoDel Algorithm";
public final static String[] FILE_ARTEFACT_TAGS = {"codel", "sample code"};
public final static String FILE_ARTEFACT_BINDER = BINDER_PROGRAMMING_SAMPLES;
public final static String FILE_ARTEFACT_PAGE = "cpp";
public final static String FILE_ARTEFACT_STRUCTURE = "issue 1";
public final static String LEARNING_JOURNAL_TITLE = "Programming Topics";
public final static String LEARNING_JOURNAL_DESCRIPTION = "Some hot programming topics";
public final static String[] LEARNING_JOURNAL_TAGS = {"programming", "c", "c++"};
public final static String LEARNING_JOURNAL_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String LEARNING_JOURNAL_PAGE = "journal";
public final static String LEARNING_JOURNAL_STRUCTURE = "2012/08/13";
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_CONTENT = "1. Two threads\n----------------\n - Keep in mind to sync two threads you need in each thread a conditional lock and method call to wake up the other thread\n";
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_TITLE = "syncing threads";
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_DESCRIPTION = "Notes on using conditional locks.";
public final static String[] TEXT_ARTEFACT_CREATED_WITHIN_BINDER_TAGS = {"programming", "threads", "thread safety", "conditional lock"};
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_PAGE = "thread safety";
public final static String TEXT_ARTEFACT_CREATED_WITHIN_BINDER_STRUCTURE = "issue 4";
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_PATH = "/org/olat/portfolio/syncing_threads.c";
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_TITLE = "conditional locks";
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_DESCRIPTION = "Syncing two posix threads using conditional locks";
public final static String[] FILE_ARTEFACT_CREATED_WITHIN_BINDER_TAGS = {"programming", "c", "mutex", "thread", "condition", "signal", "wait"};
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_BINDER = BINDER_PROGRAMMING_SAMPLES;
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_PAGE = "thread safety";
public final static String FILE_ARTEFACT_CREATED_WITHIN_BINDER_STRUCTURE = "issue 5";
public final static String LEARNING_JOURNAL_CREATED_WITHIN_BINDER_TITLE = "Threading Journal";
public final static String LEARNING_JOURNAL_CREATED_WITHIN_BINDER_DESCRIPTION = "My experiences with thread safety";
public final static String[] LEARNING_JOURNAL_CREATED_WITHIN_BINDER_TAGS = {"programming", "threads", "thread safety"};
public final static String LEARNING_JOURNAL_CREATED_WITHIN_BINDER_BINDER = BINDER_PROGRAMMING_THEORIE;
public final static String LEARNING_JOURNAL_CREATED_WITHIN_BINDER_PAGE = "thread safety";
public final static String LEARNING_JOURNAL_CREATED_WITHIN_BINDER_STRUCTURE = null;
@Deployment(testable = false)
public static WebArchive createDeployment() {
return ArquillianDeployments.createDeployment();
}
@Drone
DefaultSelenium browser;
@ArquillianResource
URL deploymentUrl;
static FunctionalUtil functionalUtil;
static FunctionalHomeSiteUtil functionalHomeSiteUtil;
static FunctionalRepositorySiteUtil functionalRepositorySiteUtil;
static FunctionalCourseUtil functionalCourseUtil;
static FunctionalEPortfolioUtil functionalEportfolioUtil;
static FunctionalVOUtil functionalVOUtil;
static UserVO user;
static List<Binder> map = new ArrayList<Binder>();
static boolean initialized = false;
@Before
public void setup() throws IOException, URISyntaxException{
if(!initialized){
functionalUtil = new FunctionalUtil();
functionalUtil.setDeploymentUrl(deploymentUrl.toString());
functionalHomeSiteUtil = functionalUtil.getFunctionalHomeSiteUtil();
functionalRepositorySiteUtil = functionalUtil.getFunctionalRepositorySiteUtil();
functionalCourseUtil = functionalRepositorySiteUtil.getFunctionalCourseUtil();
functionalEportfolioUtil = new FunctionalEPortfolioUtil(functionalUtil, functionalHomeSiteUtil);
functionalVOUtil = new FunctionalVOUtil(functionalUtil.getUsername(), functionalUtil.getPassword());
/* create test user with REST */
List<UserVO> userVO = functionalVOUtil.createTestUsers(deploymentUrl, 1);
user = userVO.get(0);
initialized = true;
}
}
Object[] prepareVerification(String binderName, String binderDescription,
String pageName, String pageDescription,
String structureName, String structureDescription,
Class<?> artefactClass, String artefactName, String artefactDescription, String[] artefactTags, String[] artefactContent){
Binder binder = findBinderByName(map, binderName);
if(binder == null){
binder = new Binder(binderName, binderDescription);
map.add(binder);
}
Binder.Page page = findPageByName(binder.page, pageName);
if(page == null){
page = binder.new Page(pageName, pageDescription);
page.parent = binder;
binder.page.add(page);
}
Binder.Page.Structure structure = findStructureByName(page.child, structureName);
if(structure == null && structureName != null){
structure = page.new Structure(structureName, structureDescription);
structure.parent = page;
page.child.add(structure);
}
Binder.Page.Artefact artefact = findArtefactByName(page.child, artefactName);
if(artefact == null && structure != null){
artefact = findArtefactByName(structure.child, artefactName);
}
if(artefact == null){
artefact = ArtefactFactory.newArtefact(page, artefactClass, artefactName, artefactDescription, artefactTags, artefactContent);
if(structure != null){
artefact.parent = structure;
structure.child.add(artefact);
}else{
artefact.parent = page;
page.child.add(artefact);
}
}
Object[] retval = new Object[]{binder, page, structure, artefact};
return(retval);
}
Binder findBinderByName(List<Binder> binder, String name){
if(name == null)
return(null);
for(Binder current: binder){
if(name.equals(current.binderName)){
return(current);
}
}
return(null);
}
Binder.Page findPageByName(List<Binder.Page> page, String name){
if(name == null)
return(null);
for(Binder.Page current: page){
if(name.equals(current.pageName)){
return(current);
}
}
return(null);
}
Binder.Page.Artefact findArtefactByName(List<?> list, String name){
if(name == null)
return(null);
for(Object current: list){
if(current instanceof Binder.Page.Artefact && name.equals(((Binder.Page.Artefact) current).artefactName)){
return((Binder.Page.Artefact) current);
}
}
return(null);
}
Binder.Page.Structure findStructureByName(List<?> list, String name){
if(name == null)
return(null);
for(Object current: list){
if(current instanceof Binder.Page.Structure && name.equals(((Binder.Page.Structure) current).structureName)){
return((Binder.Page.Structure) current);
}
}
return(null);
}
/**
* verifies the the tags and content
*
* @param artefact
* @return
*/
boolean checkArtefact(Binder.Page.Artefact artefact){
if(artefact instanceof Binder.Page.JournalArtefact)
return(true);
if(artefact.parent instanceof Binder.Page.Structure){
if(!functionalEportfolioUtil.openArtefact(browser,
((Binder)((Binder.Page)((Binder.Page.Structure) artefact.parent).parent).parent).binderName,
((Binder.Page)((Binder.Page.Structure) artefact.parent).parent).pageName,
((Binder.Page.Structure) artefact.parent).structureName,
artefact.artefactName)){
return(false);
}
}else{
if(!functionalEportfolioUtil.openArtefact(browser,
((Binder)((Binder.Page)((Binder.Page.Structure) artefact.parent).parent).parent).binderName,
((Binder.Page)((Binder.Page.Structure) artefact.parent).parent).pageName,
null,
artefact.artefactName)){
return(false);
}
}
/* check tags */
StringBuffer selectorBuffer = new StringBuffer();
selectorBuffer.append("xpath=//div[contains(@class, '")
.append(functionalEportfolioUtil.getArtefactCss())
.append("')]//div[contains(@class, '")
.append(functionalEportfolioUtil.getTagIconCss())
.append("')]//div[");
boolean hasPrev = false;
for(String currentTag: artefact.tags){
if(hasPrev){
selectorBuffer.append(" and ");
}else{
hasPrev = true;
}
selectorBuffer.append("contains(text(), '")
.append(currentTag)
.append("')");
}
selectorBuffer.append("]");
if(!browser.isElementPresent(selectorBuffer.toString())){
return(false);
}
if(!functionalEportfolioUtil.closeArtefact(browser)){
return(false);
}
/* compare business paths */
//TODO:JK: uncomment this code
/* business paths aren't reliable, yet */
// if(!functionalEportfolioUtil.clickArtefactContent(browser)){
// return(false);
// }
//
// String path0 = functionalUtil.currentBusinessPath(browser);
//
// if(!artefact.open(browser, deploymentUrl)){
// return(false);
// }
//
// String path1 = functionalUtil.currentBusinessPath(browser);
//
// if(path0 == null || !path0.equals(path1)){
// return(false);
// }
/* verify content */
artefact.open(browser, deploymentUrl);
String currentContent = null;
while((currentContent = artefact.nextContent()) != null){
if(!functionalUtil.waitForPageToLoadContent(browser, null,
currentContent,
WaitLimitAttribute.VERY_SAVE, null,
false)){
return(false);
}
}
return(true);
}
/**
* verifies the specified binder
*
* @param binder
* @return
*/
boolean checkMap(Binder binder){
if(!functionalEportfolioUtil.openBinder(browser, binder.binderName)){
return(false);
}
/* check binder structure */
for(Binder.Page currentPage: binder.page){
if(currentPage.ignore){
continue;
}
/* check page */
if(!functionalEportfolioUtil.pageExists(browser, binder.binderName, currentPage.pageName)){
return(false);
}
//TODO:JK: doesn't check the page's description
/* traverse tree */
for(Object currentPageChild: currentPage.child){
if(currentPageChild instanceof Binder.Page.Artefact){
Binder.Page.Artefact currentArtefact = (Binder.Page.Artefact) currentPageChild;
if(currentArtefact.ignore){
continue;
}
/* check artefact */
if(!functionalEportfolioUtil.artefactExists(browser, binder.binderName, currentPage.pageName, null, currentArtefact.artefactName)){
return(false);
}
//TODO:JK: doesn't check the artefact's description
}else{
Binder.Page.Structure currentStructure = (Binder.Page.Structure) currentPageChild;
if(currentStructure.ignore){
continue;
}
/* check structure */
if(!functionalEportfolioUtil.structureExists(browser, binder.binderName, currentPage.pageName, currentStructure.structureName)){
return(false);
}
//TODO:JK: doesn't check the structure's description
/* traverse tree */
for(Binder.Page.Artefact currentArtefact: currentStructure.child){
if(currentArtefact.ignore){
continue;
}
/* check artefact */
if(!functionalEportfolioUtil.artefactExists(browser, binder.binderName, currentPage.pageName, currentStructure.structureName, currentArtefact.artefactName)){
return(false);
}
//TODO:JK: doesn't check the artefact's description
}
}
}
}
return(true);
}
@Test
@RunAsClient
public void checkUploadFileArtefact() throws URISyntaxException, MalformedURLException{
/*
* Prepare for verification
*/
Object[] retval = prepareVerification(FILE_ARTEFACT_BINDER, null,
FILE_ARTEFACT_PAGE, null,
FILE_ARTEFACT_STRUCTURE, null,
FileArtefact.class, FILE_ARTEFACT_TITLE, FILE_ARTEFACT_DESCRIPTION, FILE_ARTEFACT_TAGS, null);
Binder binder = (Binder) retval[0];
Binder.Page page = (Binder.Page) retval[1];
Binder.Page.Structure structure = (Binder.Page.Structure) retval[2];
Binder.Page.Artefact artefact = (Binder.Page.Artefact) retval[3];
/*
* Test case
*/
/* login for test setup */
Assert.assertTrue(functionalUtil.login(browser, user.getLogin(), user.getPassword(), true));
/* create binder, page or structure if necessary */
Assert.assertTrue(functionalEportfolioUtil.createElements(browser, FILE_ARTEFACT_BINDER, FILE_ARTEFACT_PAGE, FILE_ARTEFACT_STRUCTURE));
/* upload file artefact */
Assert.assertTrue(functionalEportfolioUtil.uploadFileArtefact(browser, FILE_ARTEFACT_BINDER, FILE_ARTEFACT_PAGE, FILE_ARTEFACT_STRUCTURE,
FunctionalArtefactTest.class.getResource(FILE_ARTEFACT_PATH).toURI(),
FILE_ARTEFACT_TITLE, FILE_ARTEFACT_DESCRIPTION,
FILE_ARTEFACT_TAGS));
/*
* Test for content and make assumptions if the changes were applied.
* Keep it simple use quick access with business paths.
*/
binder.ignore = false;
page.ignore = false;
structure.ignore = false;
artefact.ignore = false;
/* verify */
Assert.assertTrue(checkArtefact(artefact));
Assert.assertTrue(checkMap(binder));
functionalUtil.logout(browser);
}
@Test
@RunAsClient
public void checkUploadFileArtefactWithinBinder() throws MalformedURLException, URISyntaxException{
/*
* Prepare for verification
*/
Object[] retval = prepareVerification(FILE_ARTEFACT_CREATED_WITHIN_BINDER_BINDER, null,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_PAGE, null,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_STRUCTURE, null,
FileArtefact.class,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_TITLE, FILE_ARTEFACT_CREATED_WITHIN_BINDER_DESCRIPTION, FILE_ARTEFACT_CREATED_WITHIN_BINDER_TAGS,
null);
Binder binder = (Binder) retval[0];
Binder.Page page = (Binder.Page) retval[1];
Binder.Page.Structure structure = (Binder.Page.Structure) retval[2];
Binder.Page.Artefact artefact = (Binder.Page.Artefact) retval[3];
/*
* Test case
*/
/* login for test setup */
Assert.assertTrue(functionalUtil.login(browser, user.getLogin(), user.getPassword(), true));
/* create binder, page or structure if necessary */
Assert.assertTrue(functionalEportfolioUtil.createElements(browser,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_BINDER, FILE_ARTEFACT_CREATED_WITHIN_BINDER_PAGE, FILE_ARTEFACT_CREATED_WITHIN_BINDER_STRUCTURE));
/* upload file artefact */
Assert.assertTrue(functionalEportfolioUtil.createArtefact(browser,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_BINDER, FILE_ARTEFACT_CREATED_WITHIN_BINDER_PAGE, FILE_ARTEFACT_CREATED_WITHIN_BINDER_STRUCTURE,
ArtefactAlias.FILE, FunctionalArtefactTest.class.getResource(FILE_ARTEFACT_CREATED_WITHIN_BINDER_PATH).toURI(),
FILE_ARTEFACT_CREATED_WITHIN_BINDER_TITLE, FILE_ARTEFACT_CREATED_WITHIN_BINDER_DESCRIPTION,
FILE_ARTEFACT_CREATED_WITHIN_BINDER_TAGS));
/*
* Test for content and make assumptions if the changes were applied.
* Keep it simple use quick access with business paths.
*/
binder.ignore = false;
page.ignore = false;
structure.ignore = false;
artefact.ignore = false;
/* verify */
Assert.assertTrue(checkArtefact(artefact));
Assert.assertTrue(checkMap(binder));
functionalUtil.logout(browser);
}
/**
* Description:<br/>
* Helper classes to verify interactions with openolat.
*
* @author jkraehemann, joel.kraehemann@frentix.com, frentix.com
*/
class Binder{
String binderName;
String description;
List<Page> page = new ArrayList<Page>();
boolean ignore = true;
Binder(String name, String description){
this.binderName = name;
this.description = description;
}
class Page{
Object parent = null;
String pageName;
String description;
List child = new ArrayList();
boolean ignore = true;
Page(String name, String description){
this.pageName = name;
this.description = description;
}
class Structure{
Object parent = null;
String structureName;
String description;
List<Artefact> child = new ArrayList<Artefact>();
boolean ignore = true;
Structure(String name, String description){
this.structureName = name;
this.description = description;
}
}
abstract class Artefact{
Object parent = null;
String artefactName;
String description;
String[] tags;
String[] content;
String businessPath;
boolean ignore = true;
Artefact(String name, String description, String[] tags, String[] content){
this.artefactName = name;
this.description = description;
this.tags = tags;
this.content = content;
}
boolean open(Selenium browser, URL deploymentUrl){
functionalUtil.openBusinessPath(browser, businessPath);
return(true);
}
abstract String nextContent();
}
class ForumArtefact extends Artefact{
String postTitle;
String postContent;
int nthContent = 0;
ForumArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
String nextContent(){
if(nthContent == 0){
nthContent++;
return(postTitle);
}else if(nthContent == 1){
nthContent = -1;
return(postContent);
}else{
return(null);
}
}
}
class BlogArtefact extends Artefact{
String postTitle;
String postContent;
int nthContent = 0;
BlogArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
String nextContent(){
if(nthContent == 0){
nthContent++;
return(postTitle);
}else if(nthContent == 1){
nthContent = -1;
return(null);//(postContent);
}else{
return(null);
}
}
}
class WikiArtefact extends Artefact{
String article;
int prevLine = 0;
boolean initial = true;
boolean passed = false;
WikiArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
String nextContent(){
int prevLine = this.prevLine;
if(passed){
return(null);
}
this.prevLine = article.indexOf('\n', prevLine + 1);
if(initial){
initial = false;
}else{
prevLine += 1;
}
if(this.prevLine == -1){
passed = true;
this.prevLine = article.length();
}
return(stripWikiSyntax(article.substring(prevLine, this.prevLine)));
}
String stripWikiSyntax(String line){
//TODO:JK: this method is kept very simple
line = line.replaceAll("==", "");
return(line);
}
}
class TextArtefact extends Artefact{
String content;
boolean passed = false;
TextArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
boolean open(Selenium browser, URL deploymentUrl){
/* empty */
return(true);
}
String nextContent(){
if(!passed){
passed = true;
return(content);
}else{
return(null);
}
}
}
class FileArtefact extends Artefact{
String content;
boolean passed = false;
FileArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
boolean open(Selenium browser, URL deploymentUrl){
/* empty */
return(true);
}
String nextContent(){
if(!passed){
return(content);
}else{
return(null);
}
}
}
class JournalArtefact extends Artefact{
JournalArtefact(String name, String description, String[] tags, String[] content) {
super(name, description, tags, content);
}
boolean open(Selenium browser, URL deploymentUrl){
return(functionalEportfolioUtil.openArtefact(browser, binderName, pageName, ((parent instanceof Structure) ? null: ((Structure) parent).structureName), artefactName));
}
String nextContent(){
return(null);
}
}
}
}
}
class ArtefactFactory{
static Artefact newArtefact(Page page, Class<?> artefactClass, String name, String description, String[] tags, String[] content){
if(artefactClass == null){
return(null);
}
if(artefactClass.equals(ForumArtefact.class)){
return(page.new ForumArtefact(name, description, tags, content));
}else if(artefactClass.equals(BlogArtefact.class)){
return(page.new BlogArtefact(name, description, tags, content));
}else if(artefactClass.equals(WikiArtefact.class)){
return(page.new WikiArtefact(name, description, tags, content));
}else if(artefactClass.equals(TextArtefact.class)){
return(page.new TextArtefact(name, description, tags, content));
}else if(artefactClass.equals(FileArtefact.class)){
return(page.new FileArtefact(name, description, tags, content));
}else if(artefactClass.equals(JournalArtefact.class)){
return(page.new JournalArtefact(name, description, tags, content));
}
return(null);
}
}
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
package org.olat.selenium; package org.olat.selenium;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
...@@ -34,6 +35,7 @@ import org.jboss.arquillian.graphene.page.Page; ...@@ -34,6 +35,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assume;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.olat.selenium.page.LoginPage; import org.olat.selenium.page.LoginPage;
...@@ -50,11 +52,13 @@ import org.olat.selenium.page.repository.AuthoringEnvPage.ResourceType; ...@@ -50,11 +52,13 @@ import org.olat.selenium.page.repository.AuthoringEnvPage.ResourceType;
import org.olat.selenium.page.user.UserToolsPage; import org.olat.selenium.page.user.UserToolsPage;
import org.olat.selenium.page.wiki.WikiPage; import org.olat.selenium.page.wiki.WikiPage;
import org.olat.test.ArquillianDeployments; import org.olat.test.ArquillianDeployments;
import org.olat.test.JunitTestHelper;
import org.olat.test.rest.UserRestClient; import org.olat.test.rest.UserRestClient;
import org.olat.user.restapi.UserVO; import org.olat.user.restapi.UserVO;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
@RunWith(Arquillian.class) @RunWith(Arquillian.class)
...@@ -636,6 +640,156 @@ public class PortfolioTest { ...@@ -636,6 +640,156 @@ public class PortfolioTest {
Assert.assertTrue(postTitleEl.getText().contains(postTitle)); Assert.assertTrue(postTitleEl.getText().contains(postTitle));
} }
/**
* Create a map.
* Go the "My artefacts" and create an artefact of type file. Bind it
* to the map. Check the map.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void addFileArtefact(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//File upload only work with Firefox
Assume.assumeTrue(browser instanceof FirefoxDriver);
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
loginPage
.loginAs(author.getLogin(), author.getPassword())
.resume();
//open the portfolio
PortfolioPage portfolio = userTools
.openUserToolsMenu()
.openPortfolio();
//create a map
String mapTitle = "Map-File-1-" + UUID.randomUUID();
String pageTitle = "Page-File-1-" + UUID.randomUUID();
String structureElementTitle = "Struct-File-1-" + UUID.randomUUID();
portfolio
.openMyMaps()
.createMap(mapTitle, "Need to upload some file")
.openEditor()
.selectMapInEditor(mapTitle)
.selectFirstPageInEditor()
.setPage(pageTitle, "With a little description")
.createStructureElement(structureElementTitle, "Structure description");
//go to my artefacts
portfolio = userTools
.openUserToolsMenu()
.openPortfolio()
.openMyArtefacts();
String textTitle = "File-1-" + UUID.randomUUID();
URL courseUrl = JunitTestHelper.class.getResource("file_resources/handInTopic1.pdf");
File file = new File(courseUrl.toURI());
//create the artefact
portfolio
.createFileArtefact()
.uploadFile(file)
.next()
.fillArtefactMetadatas(textTitle, "Description")
.next()
.tags("File", "PDF", "Learning")
.next()
.selectMap(mapTitle, pageTitle, structureElementTitle)
.finish();
OOGraphene.closeBlueMessageWindow(browser);
//open the portfolio
portfolio = userTools
.openUserToolsMenu()
.openPortfolio()
.openMyMaps()
.openMap(mapTitle)
.selectStructureInTOC(structureElementTitle);
//check that we see the post
By artefactTitleBy = By.cssSelector("div.panel-heading>h3");
WebElement artefactTitle = browser.findElement(artefactTitleBy);
Assert.assertTrue(artefactTitle.getText().contains(textTitle));
}
/**
* Create a map, create a new file artefact.
* Check the map and the artefact.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void addFileArtefact_withinMap(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
//File upload only work with Firefox
Assume.assumeTrue(browser instanceof FirefoxDriver);
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
loginPage
.loginAs(author.getLogin(), author.getPassword())
.resume();
//open the portfolio
PortfolioPage portfolio = userTools
.openUserToolsMenu()
.openPortfolio();
//create a map
String mapTitle = "Map-File-2-" + UUID.randomUUID();
String pageTitle = "Page-File-2-" + UUID.randomUUID();
String structureElementTitle = "Struct-File-2-" + UUID.randomUUID();
portfolio
.openMyMaps()
.createMap(mapTitle, "Need a map to upload some files quckly")
.openEditor()
.selectMapInEditor(mapTitle)
.selectFirstPageInEditor()
.setPage(pageTitle, "With a little description")
.createStructureElement(structureElementTitle, "Structure description");
//create the file artefact
ArtefactWizardPage artefactWizard = portfolio
.linkArtefact()
.addArtefact()
.createFileArtefact();
String textTitle = "File-2-" + UUID.randomUUID();
URL courseUrl = JunitTestHelper.class.getResource("file_resources/handInTopic1.pdf");
File file = new File(courseUrl.toURI());
//foolow the wizard
artefactWizard
.uploadFile(file)
.next()
.fillArtefactMetadatas(textTitle, "Description")
.next()
.tags("File", "Data", "Learning")
.next()
.selectMap(mapTitle, pageTitle, structureElementTitle)
.finish();
OOGraphene.closeBlueMessageWindow(browser);
//open the portfolio
portfolio = userTools
.openUserToolsMenu()
.openPortfolio()
.openMyMaps()
.openMap(mapTitle)
.selectStructureInTOC(structureElementTitle);
//check that we see the post
By artefactTitleBy = By.cssSelector("div.panel-heading>h3");
WebElement artefactTitle = browser.findElement(artefactTitleBy);
Assert.assertTrue(artefactTitle.getText().contains(textTitle));
}
/** /**
* Create a course with a portfolio course element. * Create a course with a portfolio course element.
* Create a template from within the portfolio course * Create a template from within the portfolio course
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
package org.olat.selenium.page.graphene; package org.olat.selenium.page.graphene;
import java.io.File;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -57,6 +58,11 @@ public class OOGraphene { ...@@ -57,6 +58,11 @@ public class OOGraphene {
((JavascriptExecutor)browser).executeScript("top.tinymce.activeEditor.setContent('" + content + "')"); ((JavascriptExecutor)browser).executeScript("top.tinymce.activeEditor.setContent('" + content + "')");
} }
public static final void uploadFile(By inputBy, File file, WebDriver browser) {
WebElement input = browser.findElement(inputBy);
input.sendKeys(file.getAbsolutePath());
}
public static final void closeBlueMessageWindow(WebDriver browser) { public static final void closeBlueMessageWindow(WebDriver browser) {
By closeButtonBy = By.cssSelector("div.o_alert_info div.o_sel_info_message i.o_icon.o_icon_close"); By closeButtonBy = By.cssSelector("div.o_alert_info div.o_sel_info_message i.o_icon.o_icon_close");
List<WebElement> closeButtons = browser.findElements(closeButtonBy); List<WebElement> closeButtons = browser.findElements(closeButtonBy);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
package org.olat.selenium.page.portfolio; package org.olat.selenium.page.portfolio;
import java.io.File;
import java.util.List; import java.util.List;
import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.drone.api.annotation.Drone;
...@@ -84,6 +85,12 @@ public class ArtefactWizardPage { ...@@ -84,6 +85,12 @@ public class ArtefactWizardPage {
return this; return this;
} }
public ArtefactWizardPage uploadFile(File file) {
By inputBy = By.cssSelector(".o_fileinput input[type='file']");
OOGraphene.uploadFile(inputBy, file, browser);
return this;
}
public ArtefactWizardPage fillArtefactMetadatas(String title, String description) { public ArtefactWizardPage fillArtefactMetadatas(String title, String description) {
By titleBy = By.cssSelector(".o_sel_ep_artefact_metadata_title input"); By titleBy = By.cssSelector(".o_sel_ep_artefact_metadata_title input");
WebElement titleEl = browser.findElement(titleBy); WebElement titleEl = browser.findElement(titleBy);
......
...@@ -74,10 +74,7 @@ public class PortfolioPage { ...@@ -74,10 +74,7 @@ public class PortfolioPage {
* @return * @return
*/ */
public ArtefactWizardPage createTextArtefact() { public ArtefactWizardPage createTextArtefact() {
By createButtonBy = By.className("o_sel_add_artfeact"); addArtefact();
WebElement createButton = browser.findElement(createButtonBy);
createButton.click();
OOGraphene.waitBusy();
By addTextArtefactBy = By.className("o_sel_add_text_artfeact"); By addTextArtefactBy = By.className("o_sel_add_text_artfeact");
OOGraphene.waitElement(addTextArtefactBy); OOGraphene.waitElement(addTextArtefactBy);
...@@ -93,10 +90,7 @@ public class PortfolioPage { ...@@ -93,10 +90,7 @@ public class PortfolioPage {
* @return * @return
*/ */
public ArtefactWizardPage createLearningJournal() { public ArtefactWizardPage createLearningJournal() {
By createButtonBy = By.className("o_sel_add_artfeact"); addArtefact();
WebElement createButton = browser.findElement(createButtonBy);
createButton.click();
OOGraphene.waitBusy();
By addJournalArtefactBy = By.className("o_sel_add_liveblog_artfeact"); By addJournalArtefactBy = By.className("o_sel_add_liveblog_artfeact");
OOGraphene.waitElement(addJournalArtefactBy); OOGraphene.waitElement(addJournalArtefactBy);
...@@ -107,6 +101,18 @@ public class PortfolioPage { ...@@ -107,6 +101,18 @@ public class PortfolioPage {
return ArtefactWizardPage.getWizard(browser); return ArtefactWizardPage.getWizard(browser);
} }
public ArtefactWizardPage createFileArtefact() {
addArtefact();
By addJournalArtefactBy = By.className("o_sel_add_upload_artfeact");
OOGraphene.waitElement(addJournalArtefactBy);
WebElement addJournalArtefactLink = browser.findElement(addJournalArtefactBy);
addJournalArtefactLink.click();
OOGraphene.waitBusy();
return ArtefactWizardPage.getWizard(browser);
}
/** /**
* Click the link to add an artefact to the map * Click the link to add an artefact to the map
* *
......
...@@ -16,17 +16,7 @@ ...@@ -16,17 +16,7 @@
<!-- debugging arguments for javaVm: -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y --> <!-- debugging arguments for javaVm: -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y -->
</configuration> </configuration>
</container> </container>
<extension qualifier="selenium">
<property name="browserCapabilities">firefox</property>
<!-- Path for Firefox if needed
<property name="capabilityWebdriverFirefoxBin">/Applications/Firefox.app/Contents/MacOS/firefox-bin</property>
-->
<!-- Not all tests pass with Chrome (issue with file upload)
<property name="browser">*googlechrome</property>
-->
</extension>
<extension qualifier="webdriver"> <extension qualifier="webdriver">
<property name="browser">safari</property> <property name="browser">safari</property>
</extension> </extension>
...@@ -35,13 +25,14 @@ ...@@ -35,13 +25,14 @@
<property name="browser">safari</property> <property name="browser">safari</property>
</extension> </extension>
<extension qualifier="graphene-firefox">
<property name="browser">firefox</property>
<property name="remoteReusable">true</property>
</extension>
<extension qualifier="phantomjs"> <extension qualifier="phantomjs">
<property name="browser">phantomjs</property> <property name="browser">phantomjs</property>
<property name="dimensions">1000x700</property> <property name="dimensions">1000x700</property>
</extension> </extension>
<extension qualifier="student">
<property name="browserCapabilities">firefox</property>
<property name="count">100</property>
</extension>
</arquillian> </arquillian>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment