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