Index: lams_tests/tests/org/lamsfoundation/lams/author/BranchingTests.java =================================================================== diff -u -r5c7d3d7e3e35175f3f828002c4a74b56a4254585 -r0b17741e05a94c4dc20f6990b5ab84ef672605fa --- lams_tests/tests/org/lamsfoundation/lams/author/BranchingTests.java (.../BranchingTests.java) (revision 5c7d3d7e3e35175f3f828002c4a74b56a4254585) +++ lams_tests/tests/org/lamsfoundation/lams/author/BranchingTests.java (.../BranchingTests.java) (revision 0b17741e05a94c4dc20f6990b5ab84ef672605fa) @@ -28,6 +28,7 @@ import org.lamsfoundation.lams.author.util.AuthorConstants; import org.lamsfoundation.lams.pages.IndexPage; import org.lamsfoundation.lams.pages.LoginPage; +import org.lamsfoundation.lams.pages.author.ConditionsPropertiesPage; import org.lamsfoundation.lams.pages.author.FLAPage; import org.lamsfoundation.lams.util.LamsUtil; import org.openqa.selenium.Point; @@ -96,7 +97,7 @@ @AfterClass public void afterClass() { - // driver.quit(); + driver.quit(); } /** @@ -660,6 +661,181 @@ } + + + + + /** + * Creates a tool output branching by dragging transitions from the same activity + * + * Here we create a small sequence with an tool input from an MCQ. + * MCQ by default has 1 question with a 1 mark output. So we create two conditions for total + * score: + * + * 1) Zero condition, if the user gets just zero (wrong answer) + * 2) One condition, if the user gets one mark (answers correctly) + * + * Then, we match the Zero condition to Branch 2 and One condition to Branch 1(default) + * + * + */ + @Test(dependsOnMethods="reOpenAndVerifyTeacherChoiceDesign") + public void createToolOutputBranching() { + + // Test data + String rangeValueZero = "0"; + String rangeValueOne = "1"; + + String conditionZeroRange = "Zero condition"; + String conditionOneRange = "One condition"; + + String branchOne = "Branch 1"; + String branchTwo = "Branch 2"; + + + clearCanvas(); + + // Drop activities in canvas + fla.dragActivityToCanvasPosition(AuthorConstants.MULTIPLE_CHOICE_TITLE, 200, 150) + .dragActivityToCanvasPosition(AuthorConstants.NOTEBOOK_TITLE, 400, 100) + .dragActivityToCanvasPosition(AuthorConstants.WIKI_TITLE, 400, 250); + + + // Draw transitions + List toActivities = new ArrayList<>(); + toActivities.add(AuthorConstants.NOTEBOOK_TITLE); + toActivities.add(AuthorConstants.WIKI_TITLE); + + fla.drawBranchingFromActivity(AuthorConstants.MULTIPLE_CHOICE_TITLE, toActivities) + .arrangeDesign(); + + fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .setBranchingType(BRANCHING_TYPE_LEARNER_OUTPUT); + + fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .setInputTool(AuthorConstants.MULTIPLE_CHOICE_TITLE) + .clickCreateConditions() + .setConditionOutput(ConditionsPropertiesPage.OUTPUT_MCQ_TOTAL_MARK) + .setOptionType(ConditionsPropertiesPage.OPTION_RANGE) + .setFromRangeValue(rangeValueZero) + .setToRangeValue(rangeValueZero) + .clickAddOptionRange() + .setConditionName(conditionZeroRange, "2") + .setFromRangeValue(rangeValueOne) + .setToRangeValue(rangeValueOne) + .clickAddOptionRange() + .setConditionName(conditionOneRange, "3") + .clickOkConditionsButton() + .matchConditionToBranch(conditionOneRange, branchOne) + .matchConditionToBranch(conditionZeroRange, branchTwo) + .clickOkMatchingConditionsToBranchesButton(); + + /// Assertions now + // Branching type + + String assertBranchingType = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .getBranchingType(); + + Assert.assertEquals(assertBranchingType, BRANCHING_TYPE_LEARNER_OUTPUT, "Branching type is incorrect"); + + + // Now get all the activity titles + List allActivityTitles = fla.getAllActivityNames(); + System.out.println("All activities:" + allActivityTitles); + + Assert.assertTrue(allActivityTitles.contains(AuthorConstants.BRANCHING_START_TITLE), + "The title " + AuthorConstants.BRANCHING_START_TITLE + " was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains(AuthorConstants.BRANCH_END_TITLE), + "The title " + AuthorConstants.BRANCH_END_TITLE + " was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains(AuthorConstants.MULTIPLE_CHOICE_TITLE), + "The title " + AuthorConstants.MULTIPLE_CHOICE_TITLE + " was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains(AuthorConstants.NOTEBOOK_TITLE), + "The title " + AuthorConstants.NOTEBOOK_TITLE + " was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains(AuthorConstants.WIKI_TITLE), + "The title " + AuthorConstants.WIKI_TITLE + " was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains("Branch 1"), + "Branch 1 was not found as an activity in the design"); + Assert.assertTrue(allActivityTitles.contains("Branch 2"), + "Branch 2 was not found as an activity in the design"); + + } + + /** + * Gives a name and saves the designs + */ + @Test(dependsOnMethods="createToolOutputBranching") + public void nameAndSaveDesignToolOutputDesign() { + + String saveResult = fla.saveAsDesign(randomDesignName + "-" + BRANCHING_TYPE_LEARNER_OUTPUT); + + Assert.assertTrue(saveResult.contains(AuthorConstants.SAVE_SEQUENCE_SUCCESS_MSG), + "Save error. Returned: " + saveResult); + } + + + + /** + * Reopen previously saved design to confirm settings were saved correctly + */ + @Test(dependsOnMethods="nameAndSaveDesignToolOutputDesign") + public void reOpenAndVerifyToolOutputDesign() { + + // Test data + final String conditionZeroRange = "Zero condition"; + final String conditionOneRange = "One condition"; + + final String branchOne = "Branch 1"; + final String branchTwo = "Branch 2"; + + clearCanvas(); + + fla.openDesign(randomDesignName + "-" + BRANCHING_TYPE_LEARNER_OUTPUT); + + + // Assertions + // Assert branching settings + + String assertBranchingType = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .getBranchingType(); + + String assertInputTool = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .getInputTool(); + + String assertToolOutput = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .clickCreateConditions().getConditionOutput(); + + + List assertAllConditions = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .clickCreateConditions().getConditionNames(); + + List assertAllMappings = fla.branchingProperties(AuthorConstants.BRANCHING_TITLE) + .clickMatchConditionsToBranchesButton().getAllMappings(); + + // Assert branching type + Assert.assertEquals(assertBranchingType, BRANCHING_TYPE_LEARNER_OUTPUT, "Branching type error"); + + // AssertInputtool + Assert.assertEquals(assertInputTool, AuthorConstants.MULTIPLE_CHOICE_TITLE, + "The input tool is incorrect"); + + // Assert Tool output + Assert.assertEquals(assertToolOutput, ConditionsPropertiesPage.OUTPUT_MCQ_TOTAL_MARK, + "The tool output is incorrect"); + + // Assert condition lists + Assert.assertTrue(assertAllConditions.contains(conditionZeroRange), + conditionZeroRange + "is not conditions list"); + Assert.assertTrue(assertAllConditions.contains(conditionOneRange), + conditionOneRange + "is not conditions list"); + + // Assert conditions to branches mapping + Assert.assertTrue(assertAllMappings.contains(conditionOneRange + " matches " + branchOne), + "Error " + conditionOneRange + " doesn't match with " + branchOne); + Assert.assertTrue(assertAllMappings.contains(conditionZeroRange + " matches " + branchTwo), + "Error " + conditionZeroRange + " doesn't match with " + branchTwo); + + } + } Index: lams_tests/tests/org/lamsfoundation/lams/pages/author/BranchingPropertiesPage.java =================================================================== diff -u -r5c7d3d7e3e35175f3f828002c4a74b56a4254585 -r0b17741e05a94c4dc20f6990b5ab84ef672605fa --- lams_tests/tests/org/lamsfoundation/lams/pages/author/BranchingPropertiesPage.java (.../BranchingPropertiesPage.java) (revision 5c7d3d7e3e35175f3f828002c4a74b56a4254585) +++ lams_tests/tests/org/lamsfoundation/lams/pages/author/BranchingPropertiesPage.java (.../BranchingPropertiesPage.java) (revision 0b17741e05a94c4dc20f6990b5ab84ef672605fa) @@ -22,8 +22,6 @@ package org.lamsfoundation.lams.pages.author; -import java.util.List; - import org.lamsfoundation.lams.pages.AbstractPage; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -34,11 +32,6 @@ public class BranchingPropertiesPage extends AbstractPage { - public BranchingPropertiesPage(WebDriver driver) { - super(driver); - // TODO Auto-generated constructor stub - } - /** * Branching properties * @@ -90,9 +83,28 @@ private WebElement maxSequences; + /** + * Tool output branching properties + * + */ + @FindBy(xpath = "/html/body/div[14]/div[2]/div/table/tbody/tr[4]/td[2]/select") + private WebElement inputToolSelect; + @FindBy(xpath = "/html/body/div[14]/div[2]/div/table/tbody/tr[5]/td/div/span") + private WebElement createConditionsButton; + @FindBy(xpath = "/html/body/div[14]/div[2]/div/table/tbody/tr[6]/td/div/span") + private WebElement matchConditionsToBranchesButton; + + + + public BranchingPropertiesPage(WebDriver driver) { + super(driver); + + } + + /** * Set branching title * @param title name for the branching @@ -175,11 +187,11 @@ * Presses the button to open the group to branching mapping UI. * @return BranchingPropertiesPage */ - public BranchingPropertiesPage clickMatchGroupsToBranches() { + public ConditionsPropertiesPage clickMatchGroupsToBranches() { matchGroupsToBranchesButton.click(); - return PageFactory.initElements(driver, BranchingPropertiesPage.class); + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); } /** @@ -263,4 +275,67 @@ } + + /** + * Design description UI component + * + * @return DescriptionPage object + */ + public ConditionsPropertiesPage conditionProperties() { + + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + + } + + + /** + * Selects the output to use for conditions + * + * @param inputTool + * @return {@link BranchingPropertiesPage} + */ + public BranchingPropertiesPage setInputTool(String inputTool) { + + Select inputToolSelector = new Select(inputToolSelect); + + inputToolSelector.selectByVisibleText(inputTool); + + return PageFactory.initElements(driver, BranchingPropertiesPage.class); + + } + + + /** + * Returns the name of the tool use as input for conditions + * @return tool name + */ + public String getInputTool() { + + Select inputToolSelector = new Select(inputToolSelect); + + return inputToolSelector.getFirstSelectedOption().getText(); + + } + + /** + * Click on the button to create conditions. + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage clickCreateConditions() { + + createConditionsButton.click(); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + + } + + public ConditionsPropertiesPage clickMatchConditionsToBranchesButton() { + + matchConditionsToBranchesButton.click(); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + } Index: lams_tests/tests/org/lamsfoundation/lams/pages/author/ConditionsPropertiesPage.java =================================================================== diff -u --- lams_tests/tests/org/lamsfoundation/lams/pages/author/ConditionsPropertiesPage.java (revision 0) +++ lams_tests/tests/org/lamsfoundation/lams/pages/author/ConditionsPropertiesPage.java (revision 0b17741e05a94c4dc20f6990b5ab84ef672605fa) @@ -0,0 +1,452 @@ +/**************************************************************** + * Copyright (C) 2014 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.pages.author; + +import java.util.ArrayList; +import java.util.List; + +import org.lamsfoundation.lams.pages.AbstractPage; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.Select; +import org.openqa.selenium.support.ui.WebDriverWait; + +public class ConditionsPropertiesPage extends AbstractPage { + + + public static final String OUTPUT_MCQ_ALL_CORRECT = "Are learner's answers all correct?"; + public static final String OUTPUT_MCQ_TOTAL_MARK = "Learner's total mark(range)"; + + public static final String OPTION_GREATER_THAN = "greater"; + public static final String OPTION_LESS_THAN = "less"; + public static final String OPTION_RANGE = "range"; + + /** + * Conditions properties + * + */ + + @FindBy(xpath = "//*[@id=\"outputSelect\"]") + private WebElement outputSelect; + + @FindBy (xpath = "//*[@id=\"rangeOptionSelect\"]") + private WebElement optionsSelect; + + // Range options + + @FindBy(xpath = "//*[@id=\"multiRangeFromSpinner\"]") + private WebElement rangeFrom; + + @FindBy(xpath = "//*[@id=\"multiRangeToSpinner\"]") + private WebElement rangeTo; + + @FindBy(xpath = "//*[@id=\"singleRangeSpinner\"]") + private WebElement singleRange; + + @FindBy(xpath = "//*[@id=\"rangeAddButton\"]/span") + private WebElement addRangeButton; + + + @FindBy(xpath = "/html/body/div[17]/div[11]/div/button[5]/span") + private WebElement okConditionsButton; + + @FindBy(xpath = "/html/body/div[17]/div[11]/div/button[4]/span") + private WebElement cancelConditionsButton; + + @FindBy(xpath = "/html/body/div[17]/div[11]/div/button[2]/span") + private WebElement removeConditionButton; + + @FindBy(xpath = "/html/body/div[17]/div[11]/div/button[1]/span") + private WebElement clearAllConditionsButton; + + + + /** + * Note that we need to use this xpath and iterate thru the elements on a + * table, so we use the " " where we'd need to change the numbering according to the + * number of labels we find in the table. + * + */ + private static final String RANGE_CONDITIONS_OPTION_LABEL = + "//*[@id=\"rangeConditions\"]/tbody/tr[ ]/td[1]/input"; + + // private static final String RANGE_CONDITIONS_CONDITION_LABEL = + // "//*[@id=\"rangeConditions\"]/tbody/tr[ ]/td[2]"; + + /** + * Match conditions to branches elements + * + */ + + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[1]") + private WebElement conditionsColumn; + + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[2]") + private WebElement branchesColumn; + + + // These buttons are to move the conditions to mapping + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[3]/div[1]/span[1]") + private WebElement toRightButton; + + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[3]/div[2]/span[1]") + private WebElement toLeftButton; + + // final mappings + + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[4]") + private WebElement mappingsConditionsColumn; + + @FindBy(xpath = "//*[@id=\"ctbDialog\"]/table/tbody/tr[3]/td[5]") + private WebElement mappingsBranchColumn; + + + @FindBy(xpath = "/html/body/div[18]/div[11]/div/button/span") + private WebElement okMatchConditionsBranchesButton; + + + public ConditionsPropertiesPage(WebDriver driver) { + super(driver); + + } + + + + /** + * Select condition output + * + * @param Condition output to select + * @return ConditionsPropertiesPage + */ + public ConditionsPropertiesPage setConditionOutput(String output) { + + Select outputSelection = new Select(outputSelect); + outputSelection.selectByVisibleText(output); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + /** + * Gets the selection for condition output + * + * @return output text (String) + */ + public String getConditionOutput() { + + Select outputSelection = new Select(outputSelect); + + return outputSelection.getFirstSelectedOption().getText(); + + } + + + /** + * Sets the option for the condition (ranges) + * @param option + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage setOptionType(String option) { + + Select optionSelector = new Select(optionsSelect); + + optionSelector.selectByValue(option); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + /** + * Gets the selected option (range) + * @return text from value of the condition + */ + public String getOptionType() { + + Select optionSelector = new Select(optionsSelect); + + return optionSelector.getFirstSelectedOption().getAttribute("value"); + } + + + /** + * Sets the value for the option when the greater or less than option was selected + * @param value the option mark/score + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage setSingleRangeValue(String value) { + + singleRange.click(); + singleRange.clear(); + singleRange.sendKeys(value); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + + } + + /** + * Returns the value set for the single range option + * @return value within input + */ + public String getSingleRangeValue() { + + singleRange.click(); + return singleRange.getAttribute("value"); + + } + + /** + * Sets the from range for an option + * @param value + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage setFromRangeValue(String value) { + + rangeFrom.click(); + rangeFrom.clear(); + rangeFrom.sendKeys(value); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + + } + + /** + * Returns the value set in the from option + * @param value + * @return String value of from option + */ + public String getFromRangeValue() { + + rangeFrom.click(); + return rangeFrom.getAttribute("value"); + } + + /** + * Sets the to range for an option + * @param value + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage setToRangeValue(String value) { + + rangeTo.click(); + rangeTo.clear(); + rangeTo.sendKeys(value); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + /** + * Returns the value set in in the To range + * @return value set in to range + */ + public String getToRangeValue() { + + return rangeTo.getAttribute("value"); + + } + + + /** + * Clicks on the Add option for range + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage clickAddOptionRange() { + + addRangeButton.click(); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + /** + * Sets the name for the condition + * @param conditionName + * @param order this is for the xpath order (starts always in 2). + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage setConditionName(String conditionName, String order) { + + String inputXpath = RANGE_CONDITIONS_OPTION_LABEL.replace(" ", order); + System.out.println("inputXpath: " + inputXpath); + + WebElement input = driver.findElement(By.xpath(inputXpath)); + + input.click(); + input.clear(); + input.sendKeys(conditionName); + + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + /** + * Returns all the available conditions in a List + * @return + */ + public List getConditionNames() { + + List elements = driver.findElements(By.xpath("id('rangeConditions')/tbody//tr[*]/td[1]/input")); + List conditionNames = new ArrayList(); + + for (int i = 0; i < elements.size(); i++) { + WebElement element = elements.get(i); + + conditionNames.add(element.getAttribute("value")); + + + } + + cancelConditionsButton.click(); + + return conditionNames; + } + + + /** + * Click on OK for conditions. + * + * This should open the conditions to branches matching page. + * + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage clickOkConditionsButton() { + + okConditionsButton.click(); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + + /** + * Matches conditions to branches + * + * Given a condition name, it matches it to a branch + * + * @param conditionName + * @param branchName + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage matchConditionToBranch(String conditionName, String branchName) { + + // Let's iterate thru the conditions and click on the one sent + + List allConditions = conditionsColumn.findElements(By.tagName("div")); + + // We've got to use this wait as otherwise the javascript isn't as fast to return the txt + // within the div + WebDriverWait wait = new WebDriverWait(driver, 10); + + + for (WebElement condition : allConditions) { + wait.until(ExpectedConditions.elementToBeClickable(condition)); + String name = condition.getText(); + + if (conditionName.equals(name.trim())) { + System.out.print("condition name: " + name); + condition.click(); + break; + } + } + + + // Now iterate thru the branches and choose the one sent + + List allBranches = branchesColumn.findElements(By.tagName("div")); + + for (WebElement branch : allBranches) { + wait.until(ExpectedConditions.elementToBeClickable(branch)); + String name = branch.getText(); + + // when doing the comparison we remove the "(default)" string just to make + // that it matches even when we don't know which one is the default branch + + if (branchName.equals(name.replace("(default)", "").trim())) { + System.out.println(" matching with branch name: " + name); + branch.click(); + break; + } + } + + toRightButton.click(); + + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + + /** + * Click OK Matching conditions. + * + * Note that all of the conditions must be matched to branches. Otherwise on clicking this button + * an alert will show stating that all conditions must be matched before finishing and that by + * default all matchless conditions will be matched to the default branch. + * + * @return {@link ConditionsPropertiesPage} + */ + public ConditionsPropertiesPage clickOkMatchingConditionsToBranchesButton() { + + okMatchConditionsBranchesButton.click(); + + return PageFactory.initElements(driver, ConditionsPropertiesPage.class); + } + + + /** + * Returns all the condition to branches mappings + * + * @return all conditions available in the format "{condition} + ' matches ' + {branch}" + */ + public List getAllMappings() { + + List allMappings = new ArrayList(); + WebDriverWait wait = new WebDriverWait(driver, 10); + + List allConditions = mappingsConditionsColumn.findElements(By.tagName("div")); + + List conditions = new ArrayList(); + for (WebElement condition : allConditions) { + wait.until(ExpectedConditions.elementToBeClickable(condition)); + conditions.add(condition.getText()); + } + + + List allBranches = mappingsBranchColumn.findElements(By.tagName("div")); + + List branches = new ArrayList(); + for (WebElement branch : allBranches) { + wait.until(ExpectedConditions.elementToBeClickable(branch)); + branches.add(branch.getText()); + } + + // Create final mapping list + for (int i = 0; i < conditions.size(); i++) { + allMappings.add(conditions.get(i) + " matches " + branches.get(i)); + } + + + return allMappings; + + } + + +}