From a08a8140a40da81bdc78e6377bd5da996195410c Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 3 Jul 2014 09:14:35 +0200 Subject: [PATCH] OO-1068: 2 selenium test for the portfolio (file artefacts) --- .../portfolio/FunctionalArtefactTest.java | 812 ------------------ .../java/org/olat/selenium/PortfolioTest.java | 154 ++++ .../selenium/page/graphene/OOGraphene.java | 6 + .../page/portfolio/ArtefactWizardPage.java | 7 + .../page/portfolio/PortfolioPage.java | 22 +- src/test/resources/arquillian.xml | 21 +- 6 files changed, 187 insertions(+), 835 deletions(-) delete mode 100644 src/test/java/org/olat/portfolio/FunctionalArtefactTest.java diff --git a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java b/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java deleted file mode 100644 index 5786d400923..00000000000 --- a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java +++ /dev/null @@ -1,812 +0,0 @@ -/** - * <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); - } -} diff --git a/src/test/java/org/olat/selenium/PortfolioTest.java b/src/test/java/org/olat/selenium/PortfolioTest.java index 37eb6cdfb9a..3e7b14d7b9f 100644 --- a/src/test/java/org/olat/selenium/PortfolioTest.java +++ b/src/test/java/org/olat/selenium/PortfolioTest.java @@ -19,6 +19,7 @@ */ package org.olat.selenium; +import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; @@ -34,6 +35,7 @@ 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.Assume; import org.junit.Test; import org.junit.runner.RunWith; import org.olat.selenium.page.LoginPage; @@ -50,11 +52,13 @@ import org.olat.selenium.page.repository.AuthoringEnvPage.ResourceType; import org.olat.selenium.page.user.UserToolsPage; import org.olat.selenium.page.wiki.WikiPage; import org.olat.test.ArquillianDeployments; +import org.olat.test.JunitTestHelper; 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; +import org.openqa.selenium.firefox.FirefoxDriver; @RunWith(Arquillian.class) @@ -636,6 +640,156 @@ public class PortfolioTest { 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 template from within the portfolio course diff --git a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java index 879266abe76..d427d4e713f 100644 --- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java +++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java @@ -19,6 +19,7 @@ */ package org.olat.selenium.page.graphene; +import java.io.File; import java.util.List; import java.util.concurrent.TimeUnit; @@ -57,6 +58,11 @@ public class OOGraphene { ((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) { 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); diff --git a/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java b/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java index 5c57b62c0de..968bfb5ed8d 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java @@ -19,6 +19,7 @@ */ package org.olat.selenium.page.portfolio; +import java.io.File; import java.util.List; import org.jboss.arquillian.drone.api.annotation.Drone; @@ -84,6 +85,12 @@ public class ArtefactWizardPage { 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) { By titleBy = By.cssSelector(".o_sel_ep_artefact_metadata_title input"); WebElement titleEl = browser.findElement(titleBy); diff --git a/src/test/java/org/olat/selenium/page/portfolio/PortfolioPage.java b/src/test/java/org/olat/selenium/page/portfolio/PortfolioPage.java index 3c8f94915db..4683d9a78c0 100644 --- a/src/test/java/org/olat/selenium/page/portfolio/PortfolioPage.java +++ b/src/test/java/org/olat/selenium/page/portfolio/PortfolioPage.java @@ -74,10 +74,7 @@ public class PortfolioPage { * @return */ public ArtefactWizardPage createTextArtefact() { - By createButtonBy = By.className("o_sel_add_artfeact"); - WebElement createButton = browser.findElement(createButtonBy); - createButton.click(); - OOGraphene.waitBusy(); + addArtefact(); By addTextArtefactBy = By.className("o_sel_add_text_artfeact"); OOGraphene.waitElement(addTextArtefactBy); @@ -93,10 +90,7 @@ public class PortfolioPage { * @return */ public ArtefactWizardPage createLearningJournal() { - By createButtonBy = By.className("o_sel_add_artfeact"); - WebElement createButton = browser.findElement(createButtonBy); - createButton.click(); - OOGraphene.waitBusy(); + addArtefact(); By addJournalArtefactBy = By.className("o_sel_add_liveblog_artfeact"); OOGraphene.waitElement(addJournalArtefactBy); @@ -107,6 +101,18 @@ public class PortfolioPage { 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 * diff --git a/src/test/resources/arquillian.xml b/src/test/resources/arquillian.xml index dc28e25e6e7..e9f68c5bccf 100644 --- a/src/test/resources/arquillian.xml +++ b/src/test/resources/arquillian.xml @@ -16,17 +16,7 @@ <!-- debugging arguments for javaVm: -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y --> </configuration> </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"> <property name="browser">safari</property> </extension> @@ -35,13 +25,14 @@ <property name="browser">safari</property> </extension> + <extension qualifier="graphene-firefox"> + <property name="browser">firefox</property> + <property name="remoteReusable">true</property> + </extension> + <extension qualifier="phantomjs"> <property name="browser">phantomjs</property> <property name="dimensions">1000x700</property> </extension> - <extension qualifier="student"> - <property name="browserCapabilities">firefox</property> - <property name="count">100</property> - </extension> </arquillian> -- GitLab