diff --git a/functional-tests-jcommune/README.md b/functional-tests-jcommune/README.md index 57331db2..ff31ee6f 100644 --- a/functional-tests-jcommune/README.md +++ b/functional-tests-jcommune/README.md @@ -1,6 +1,6 @@ ####Test Methods: * All test cases are kept in separate test methods. To simplify future debugging we're not using `@DataProvider` -* Test methods should be named \[action\]_\[condition\]_\[expected result\]_\[TestCaseId\], -* e.g.: `signIn_withoutEnteringData_shouldFail_TC1234()`. +* Test methods should be named \[action\]_\[condition\]_\[expected result\], +* e.g.: `signIn_withoutEnteringData_shouldFail`. * Methods should be marked with groups `@Test(groups = {"sanity", "primary", "regression"})` depending on the type of test. These groups are going to be run separately. \ No newline at end of file diff --git a/functional-tests-jcommune/src/test/java/org/jtalks/tests/jcommune/TopicDraftTest.java b/functional-tests-jcommune/src/test/java/org/jtalks/tests/jcommune/TopicDraftTest.java new file mode 100644 index 00000000..10a04607 --- /dev/null +++ b/functional-tests-jcommune/src/test/java/org/jtalks/tests/jcommune/TopicDraftTest.java @@ -0,0 +1,39 @@ +package org.jtalks.tests.jcommune; + +import org.jtalks.tests.jcommune.webdriver.action.Topics; +import org.jtalks.tests.jcommune.webdriver.action.Users; +import org.jtalks.tests.jcommune.webdriver.entity.topic.Draft; +import org.jtalks.tests.jcommune.webdriver.entity.topic.Topic; +import org.jtalks.tests.jcommune.webdriver.exceptions.ValidationException; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import static org.assertj.core.api.StrictAssertions.assertThat; +import static org.jtalks.tests.jcommune.webdriver.JCommuneSeleniumConfig.driver; +import static org.jtalks.tests.jcommune.webdriver.page.Pages.mainPage; +import static org.jtalks.tests.jcommune.webdriver.page.Pages.postPage; + +/** + * Created by @baranov.r.p + */ +public class TopicDraftTest { + + @BeforeMethod(alwaysRun = true) + @Parameters({"appUrl"}) + public void setupCase(String appUrl) throws ValidationException { + driver.get(appUrl); + mainPage.logOutIfLoggedIn(driver); + } + + @Test(groups = {"primary"}) + public void autoSaveDraft_MoveFocus_ShouldSave() { + Users.signUpAndSignIn(); + Topic topic = new Topic(); + Topic createdTopic = Topics.createTopic(topic); + + Draft draft = Topics.typeAnswer(createdTopic).loseFocus(); + + assertThat(draft.getPostContent()).isEqualTo(postPage.reloadAndFindDraftContent()); + } +} \ No newline at end of file diff --git a/functional-tests-jcommune/src/test/resources/testng.xml b/functional-tests-jcommune/src/test/resources/testng.xml index e7aa2941..0dacab2b 100644 --- a/functional-tests-jcommune/src/test/resources/testng.xml +++ b/functional-tests-jcommune/src/test/resources/testng.xml @@ -26,6 +26,7 @@ + @@ -50,6 +51,7 @@ + diff --git a/jcommune-webdriver/pom.xml b/jcommune-webdriver/pom.xml index 3c8cf301..6895d415 100644 --- a/jcommune-webdriver/pom.xml +++ b/jcommune-webdriver/pom.xml @@ -62,6 +62,11 @@ spring-web 3.1.0.RELEASE + + org.assertj + assertj-core + 3.1.0 + diff --git a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/JCommuneSeleniumConfig.java b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/JCommuneSeleniumConfig.java index 8a190fa4..c5060b12 100644 --- a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/JCommuneSeleniumConfig.java +++ b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/JCommuneSeleniumConfig.java @@ -2,6 +2,7 @@ import org.jtalks.tests.jcommune.webdriver.page.Pages; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.CapabilityType; @@ -33,6 +34,7 @@ public class JCommuneSeleniumConfig { public static WebDriver driver = null; public static String webdriverType; private static String appUrl; + private static JavascriptExecutor js = null; public static Capabilities getCapabilities() { return ((RemoteWebDriver) driver).getCapabilities(); @@ -66,6 +68,7 @@ private void initDriver(String defaultSeleniumServerUrl) throws MalformedURLExce LOGGER.info("Selenium WebDriver URL: [{}]", seleniumUrl); driver = new RemoteWebDriver(new URL(seleniumUrl), capabilities); driver.manage().timeouts().implicitlyWait(SELENIUM_TIMEOUT_SEC, TimeUnit.SECONDS); + js = (JavascriptExecutor) driver; } private String getOs() { @@ -121,4 +124,8 @@ public void destroy() { public static String getAppUrl() { return appUrl; } -} + + public static JavascriptExecutor getJs() { + return js; + } +} \ No newline at end of file diff --git a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Pages.java b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Pages.java new file mode 100644 index 00000000..d8863df7 --- /dev/null +++ b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Pages.java @@ -0,0 +1,23 @@ +package org.jtalks.tests.jcommune.webdriver.action; + +import org.openqa.selenium.WebElement; +import ru.yandex.qatools.allure.annotations.Step; + +import static org.jtalks.tests.jcommune.webdriver.JCommuneSeleniumConfig.driver; +import static org.jtalks.tests.jcommune.webdriver.JCommuneSeleniumConfig.getJs; + +/** + * @author baranov.r.p + */ +public class Pages { + + @Step + public static void refreshPage() { + driver.navigate().refresh(); + } + + @Step + public static void scrollToEl(WebElement el) { + getJs().executeScript("arguments[0].scrollIntoView(false);", el); + } +} \ No newline at end of file diff --git a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Topics.java b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Topics.java index 5516fe4d..f0381a7c 100644 --- a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Topics.java +++ b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/action/Topics.java @@ -20,6 +20,7 @@ import org.jtalks.tests.jcommune.webdriver.entity.branch.Branch; import org.jtalks.tests.jcommune.webdriver.entity.topic.CodeReview; import org.jtalks.tests.jcommune.webdriver.entity.topic.CodeReviewComment; +import org.jtalks.tests.jcommune.webdriver.entity.topic.Draft; import org.jtalks.tests.jcommune.webdriver.entity.topic.Post; import org.jtalks.tests.jcommune.webdriver.entity.topic.Topic; import org.jtalks.tests.jcommune.webdriver.entity.user.User; @@ -27,8 +28,6 @@ import org.jtalks.tests.jcommune.webdriver.exceptions.PermissionsDeniedException; import org.jtalks.tests.jcommune.webdriver.exceptions.TimeoutException; import org.jtalks.tests.jcommune.webdriver.exceptions.ValidationException; -import static org.jtalks.tests.jcommune.webdriver.JCommuneSeleniumConfig.driver; - import org.jtalks.tests.jcommune.webdriver.page.PostPage; import org.jtalks.tests.jcommune.webdriver.page.TopicPage; import org.openqa.selenium.By; @@ -42,9 +41,10 @@ import java.util.List; import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric; import static org.jtalks.tests.jcommune.utils.ReportNgLogger.info; +import static org.jtalks.tests.jcommune.webdriver.JCommuneSeleniumConfig.driver; import static org.jtalks.tests.jcommune.webdriver.page.Pages.*; -import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric; /** * Contain topic actions like creating, deleting etc. @@ -101,6 +101,18 @@ public static Post postAnswer(Topic topic) throws PermissionsDeniedException, Co return newPost; } + @Step + public static Draft typeAnswer(Topic topic) throws PermissionsDeniedException, CouldNotOpenPageException { + openRequiredTopic(topic); + + Post newDraft = new Draft(randomAlphanumeric(200)); + topic.addPost(newDraft); + postPage.getMessageField().sendKeys(newDraft.getPostContent()); + + info("Draft in topic [" + topic.getTitle() + "] saving ..."); + return (Draft) newDraft; + } + @Step public static void postAnswer(Topic topic, Post post) throws PermissionsDeniedException, CouldNotOpenPageException, ValidationException { openRequiredTopic(topic); @@ -430,4 +442,4 @@ public static void deleteCodeReviewComment(CodeReview codeReview, CodeReviewComm postPage.clickDeleteInCodeReviewCommentContainingString(codeReviewComment.getPostContent()); postPage.closeDeleteCRCommentConfirmDialogOk(); } -} +} \ No newline at end of file diff --git a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/entity/topic/Draft.java b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/entity/topic/Draft.java new file mode 100644 index 00000000..6133e91c --- /dev/null +++ b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/entity/topic/Draft.java @@ -0,0 +1,22 @@ +package org.jtalks.tests.jcommune.webdriver.entity.topic; +import ru.yandex.qatools.allure.annotations.Step; + +import static org.jtalks.tests.jcommune.utils.ReportNgLogger.info; +import static org.jtalks.tests.jcommune.webdriver.page.Pages.postPage; + +/** + * @author baranov.r.p + */ +public class Draft extends Post { + + public Draft(String postContent) { + super(postContent); + } + + @Step + public Draft loseFocus() { + info("Trying to set focus on link post button"); + postPage.setFocusOnPostLinkButton(); + return this; + } +} \ No newline at end of file diff --git a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/page/PostPage.java b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/page/PostPage.java index 1cae408e..5bb0ac52 100644 --- a/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/page/PostPage.java +++ b/jcommune-webdriver/src/main/java/org/jtalks/tests/jcommune/webdriver/page/PostPage.java @@ -19,6 +19,8 @@ import static org.jtalks.tests.jcommune.utils.ReportNgLogger.info; import static org.jtalks.tests.jcommune.webdriver.page.Pages.moveTopicEditor; +import static org.jtalks.tests.jcommune.webdriver.page.Pages.postPage; +import static org.jtalks.tests.jcommune.webdriver.action.Pages.scrollToEl; /** * @author masyan @@ -218,6 +220,19 @@ public class PostPage { @FindBy(xpath = codeReviewCommentBodyErrorMessageSel) private WebElement codeReviewCommentBodyErrorMessage; + @FindBy(tagName = "textarea") + private WebElement textareaEditor; + + @FindBy(id = "postDto") + private WebElement postDto; + + // space symbol is used for localization compatibility, in any language counter message will have spaces + @FindBy(xpath = "//span[@id='counter' and contains(text(),' ')]") + private WebElement draftCounterActive; + + @FindBy(className = "postLink") + private WebElement postLink; + private WebDriver driver; public PostPage(WebDriver driver) { @@ -391,6 +406,37 @@ public boolean isUserInsideCorrectTopic(String title) { return false; } + public void setFocusOnPostLinkButton() { + // move focus outside of textarea + getPostLinkButton().sendKeys(""); + info("Focus set on edit post button"); + } + + public String scrollDownAndFindDraftCountMessage() { + // scroll page to the bottom of post editor, + // guarantee that draft counter message will be visible for driver + scrollToEl(getPostDto()); + info("Trying to find draft counter message"); + return getDraftCounterActiveSpan().getText(); + } + + public String reloadAndFindDraftContent() { + checkCounter(); + // reload page to get confidence that draft really saved + org.jtalks.tests.jcommune.webdriver.action.Pages.refreshPage(); + info("Trying to find draft content"); + return getTextareaEditor().getAttribute("value"); + } + + public boolean checkCounter() { + try { + postPage.scrollDownAndFindDraftCountMessage(); + } catch (Exception e) { + throw new RuntimeException("Draft was not created", e); + } + return true; + } + //Getters public WebElement getTopicTitle() { @@ -550,4 +596,20 @@ public WebElement getCRCommentConfirmButton() { public WebElement getCRCommentBodyErrorMessage() { return codeReviewCommentBodyErrorMessage; } -} + + public WebElement getPostDto() { + return postDto; + } + + public WebElement getDraftCounterActiveSpan() { + return draftCounterActive; + } + + public WebElement getTextareaEditor() { + return textareaEditor; + } + + public WebElement getPostLinkButton() { + return postLink; + } +} \ No newline at end of file