() {
@Override
public Alert apply(WebDriver driver) {
try {
@@ -105,16 +111,50 @@ public Alert apply(WebDriver driver) {
});
}
+ /**
+ * @deprecated Use the overload which includes a message
+ */
+ @Deprecated
protected P refreshPageUntil(P currentPage,
Predicate predicate) {
- waitForAMoment().until(predicate);
+ return refreshPageUntil(currentPage, predicate, null);
+ }
+
+ /**
+ * @param currentPage
+ * @param predicate
+ * @param message description of predicate
+ * @param
+ * @return
+ */
+ protected
P refreshPageUntil(P currentPage,
+ Predicate predicate, String message) {
+ waitForAMoment().withMessage(message).until(predicate);
PageFactory.initElements(driver, currentPage);
return currentPage;
}
+ /**
+ * @deprecated Use the overload which includes a message
+ */
+ @Deprecated
protected T refreshPageUntil(P currentPage,
Function function) {
- T done = waitForAMoment().until(function);
+ return refreshPageUntil(currentPage, function, null);
+ }
+
+ /**
+ *
+ * @param currentPage
+ * @param function
+ * @param message description of function
+ * @param
+ * @param
+ * @return
+ */
+ protected T refreshPageUntil(P currentPage,
+ Function function, String message) {
+ T done = waitForAMoment().withMessage(message).until(function);
PageFactory.initElements(driver, currentPage);
return done;
}
@@ -130,56 +170,61 @@ protected T refreshPageUntil(P currentPage,
*/
public void
waitFor(final Callable callable, final Matcher matcher) {
- waitForAMoment().until(new Predicate() {
- @Override
- public boolean apply(WebDriver input) {
- try {
- T result = callable.call();
- if (!matcher.matches(result)) {
- matcher.describeMismatch(result,
- new Description.NullDescription());
+ waitForAMoment().withMessage(StringDescription.toString(matcher)).until(
+ new Predicate() {
+ @Override
+ public boolean apply(WebDriver input) {
+ try {
+ T result = callable.call();
+ if (!matcher.matches(result)) {
+ matcher.describeMismatch(result,
+ new Description.NullDescription());
+ }
+ return matcher.matches(result);
+ } catch (Exception e) {
+ log.warn("exception", e);
+ return false;
+ }
}
- return matcher.matches(result);
- } catch (Exception e) {
- log.warn("exception", e);
- return false;
- }
- }
- });
+ });
+ }
+
+ /**
+ * Normally a page has no outstanding ajax requests when it has
+ * finished an operation, but some pages use long polling to
+ * "push" changes to the user, eg for the editor's event service.
+ * @return
+ */
+ protected int getExpectedBackgroundRequests() {
+ return 0;
}
/**
- * Wait for jQuery and Ajax calls to be 0
- * If either are not defined, they can be assumed to be 0.
+ * Wait for any AJAX calls to return.
*/
public void waitForPageSilence() {
- // Wait for jQuery calls to be 0
- waitForAMoment().until(new Predicate() {
+ // Wait for AJAX calls to be 0
+ waitForAMoment().withMessage("page silence").until(new Predicate() {
@Override
public boolean apply(WebDriver input) {
- int ajaxCalls;
- int jQueryCalls;
- try {
- jQueryCalls = Integer.parseInt(
- ((JavascriptExecutor) getDriver())
- .executeScript("return jQuery.active")
- .toString()
- );
- } catch (WebDriverException jCall) {
- jQueryCalls = 0;
+ Long ajaxCalls = (Long) ((JavascriptExecutor) getDriver())
+ .executeScript(
+ "return XMLHttpRequest.active");
+ if (ajaxCalls == null) {
+ if (log.isWarnEnabled()) {
+ String url = getDriver().getCurrentUrl();
+ String pageSource = ShortString.shorten(getDriver().getPageSource(), 2000);
+ log.warn("XMLHttpRequest.active is null. URL: {}\nPartial page source follows:\n{}", url, pageSource);
+ }
+ return true;
}
-
- try {
- ajaxCalls = Integer.parseInt(
- ((JavascriptExecutor) getDriver())
- .executeScript(
- "return Ajax.activeRequestCount")
- .toString()
- );
- } catch (WebDriverException jCall) {
- ajaxCalls = 0;
+ if (ajaxCalls < 0) {
+ throw new RuntimeException("XMLHttpRequest.active " +
+ "is negative. Please ensure that " +
+ "AjaxCounterBean's script is run before " +
+ "any AJAX requests.");
}
- return ajaxCalls + jQueryCalls == 0;
+ return ajaxCalls <= getExpectedBackgroundRequests();
}
});
}
@@ -190,13 +235,15 @@ public boolean apply(WebDriver input) {
* @return target WebElement
*/
public WebElement waitForWebElement(final By elementBy) {
+ String msg = "element ready " + elementBy;
+ logWaiting(msg);
waitForPageSilence();
- return waitForAMoment().until(new Function() {
+ return waitForAMoment().withMessage(msg).until(new Function() {
@Override
public WebElement apply(WebDriver input) {
- WebElement targetElement = waitForElementExists(elementBy);
+ WebElement targetElement = getDriver().findElement(elementBy);
if (!elementIsReady(targetElement)) {
- throw new NoSuchElementException("Waiting for element");
+ return null;
}
return targetElement;
}
@@ -211,14 +258,15 @@ public WebElement apply(WebDriver input) {
*/
public WebElement waitForWebElement(final WebElement parentElement,
final By elementBy) {
+ String msg = "element ready " + elementBy;
+ logWaiting(msg);
waitForPageSilence();
- return waitForAMoment().until(new Function() {
+ return waitForAMoment().withMessage(msg).until(new Function() {
@Override
public WebElement apply(WebDriver input) {
- WebElement targetElement = waitForElementExists(parentElement,
- elementBy);
+ WebElement targetElement = parentElement.findElement(elementBy);
if (!elementIsReady(targetElement)) {
- throw new NoSuchElementException("Waiting for element");
+ return null;
}
return targetElement;
}
@@ -233,8 +281,11 @@ public WebElement apply(WebDriver input) {
* @return target WebElement
*/
public WebElement waitForElementExists(final By elementBy) {
+ String msg = "element exists " + elementBy;
+ logWaiting(msg);
waitForPageSilence();
- return waitForAMoment().until(new Function() {
+ return waitForAMoment().withMessage(msg).until(
+ new Function() {
@Override
public WebElement apply(WebDriver input) {
return getDriver().findElement(elementBy);
@@ -251,8 +302,10 @@ public WebElement apply(WebDriver input) {
*/
public WebElement waitForElementExists(final WebElement parentElement,
final By elementBy) {
+ String msg = "element exists " + elementBy;
+ logWaiting(msg);
waitForPageSilence();
- return waitForAMoment().until(new Function() {
+ return waitForAMoment().withMessage(msg).until(new Function() {
@Override
public WebElement apply(WebDriver input) {
return parentElement.findElement(elementBy);
diff --git a/functional-test/src/main/java/org/zanata/page/BasePage.java b/functional-test/src/main/java/org/zanata/page/BasePage.java
index b896b431d4..0cc2833b0a 100644
--- a/functional-test/src/main/java/org/zanata/page/BasePage.java
+++ b/functional-test/src/main/java/org/zanata/page/BasePage.java
@@ -104,14 +104,16 @@ private void clickNavMenuItem(final WebElement menuItem) {
getDriver().findElement(By.id("nav-main"))
.findElement(By.tagName("a")).click();
}
- waitForAMoment().until(new Predicate() {
- @Override
- public boolean apply(WebDriver input) {
- return menuItem.isDisplayed();
- }
- });
+ waitForAMoment().withMessage("displayed: " + menuItem).until(
+ new Predicate() {
+ @Override
+ public boolean apply(WebDriver input) {
+ return menuItem.isDisplayed();
+ }
+ });
// The notifications can sometimes get in the way
- waitForAMoment().until(ExpectedConditions.elementToBeClickable(menuItem));
+ waitForAMoment().withMessage("clickable: " + menuItem).until(
+ ExpectedConditions.elementToBeClickable(menuItem));
menuItem.click();
}
@@ -263,8 +265,9 @@ public ProjectsPage submitSearch() {
}
public BasePage waitForSearchListContains(final String expected) {
- log.info("Wait for Project search list contains {}", expected);
- waitForAMoment().until(new Predicate() {
+ String msg = "Project search list contains " + expected;
+ logWaiting(msg);
+ waitForAMoment().withMessage(msg).until(new Predicate() {
@Override
public boolean apply(WebDriver input) {
return getProjectSearchAutocompleteItems().contains(expected);
@@ -281,29 +284,34 @@ public List getProjectSearchAutocompleteItems() {
public ProjectVersionsPage clickSearchEntry(final String searchEntry) {
log.info("Click Projects search result {}", searchEntry);
+ String msg = "search result " + searchEntry;
WebElement searchItem =
- waitForAMoment().until(new Function() {
- @Override
- public WebElement apply(WebDriver driver) {
- List items =
- WebElementUtil.getSearchAutocompleteResults(
- driver, "general-search-form",
- "projectAutocomplete");
-
- for (WebElement item : items) {
- if (item.getText().equals(searchEntry)) {
- return item;
+ waitForAMoment().withMessage(msg).until(
+ new Function() {
+ @Override
+ public WebElement apply(WebDriver driver) {
+ List items =
+ WebElementUtil
+ .getSearchAutocompleteResults(
+ driver,
+ "general-search-form",
+ "projectAutocomplete");
+
+ for (WebElement item : items) {
+ if (item.getText().equals(searchEntry)) {
+ return item;
+ }
+ }
+ return null;
}
- }
- return null;
- }
- });
+ });
searchItem.click();
return new ProjectVersionsPage(getDriver());
}
public void clickWhenTabEnabled(final WebElement tab) {
- waitForAMoment().until(new Predicate() {
+ String msg = "Clickable tab: " + tab;
+ waitForAMoment().withMessage(msg).until(new Predicate() {
@Override
public boolean apply(WebDriver input) {
waitForPageSilence();
diff --git a/functional-test/src/main/java/org/zanata/page/CorePage.java b/functional-test/src/main/java/org/zanata/page/CorePage.java
index 3e8d2aab58..a9e0dce373 100644
--- a/functional-test/src/main/java/org/zanata/page/CorePage.java
+++ b/functional-test/src/main/java/org/zanata/page/CorePage.java
@@ -81,7 +81,7 @@ protected void clickAndExpectErrors(WebElement button) {
public boolean apply(WebDriver input) {
return getErrors().size() > 0;
}
- });
+ }, "errors > 0");
}
public List getErrors() {
@@ -115,7 +115,7 @@ public List getErrors(final int expectedNumber) {
public boolean apply(WebDriver input) {
return getErrors().size() == expectedNumber;
}
- });
+ }, "errors = " + expectedNumber);
return getErrors();
}
@@ -126,8 +126,9 @@ public boolean apply(WebDriver input) {
* @return The full list of visible errors
*/
public List expectError(final String expected) {
- log.info("Expect error {}", expected);
- waitForAMoment().until(new Predicate() {
+ String msg = "expected error: " + expected;
+ logWaiting(msg);
+ waitForAMoment().withMessage(msg).until(new Predicate() {
@Override
public boolean apply(WebDriver input) {
return getErrors().contains(expected);
@@ -144,20 +145,22 @@ public String getNotificationMessage() {
}
public boolean expectNotification(final String notification) {
- log.info("Wait for notification {}", notification);
- return waitForAMoment().until(new Function() {
- @Override
- public Boolean apply(WebDriver driver) {
- List messages = getDriver()
- .findElement(By.id("messages"))
- .findElements(By.tagName("li"));
- List notifications = new ArrayList();
- for (WebElement message : messages) {
- notifications.add(message.getText().trim());
- }
- return notifications.contains(notification);
- }
- });
+ String msg = "notification " + notification;
+ logWaiting(msg);
+ return waitForAMoment().withMessage(msg).until(
+ new Function() {
+ @Override
+ public Boolean apply(WebDriver driver) {
+ List messages = getDriver()
+ .findElement(By.id("messages"))
+ .findElements(By.tagName("li"));
+ List notifications = new ArrayList();
+ for (WebElement message : messages) {
+ notifications.add(message.getText().trim());
+ }
+ return notifications.contains(notification);
+ }
+ });
}
public void assertNoCriticalErrors() {
@@ -193,6 +196,15 @@ public void defocus() {
}
}
+ /**
+ * Force the blur 'unfocus' process on a given element
+ */
+ public void defocus(By elementBy) {
+ log.info("Force unfocus");
+ WebElement element = getDriver().findElement(elementBy);
+ ((JavascriptExecutor) getDriver()).executeScript("arguments[0].blur()", element);
+ }
+
/* The system sometimes moves too fast for the Ajax pages, so provide a
* pause
*/
diff --git a/functional-test/src/main/java/org/zanata/page/account/EditProfilePage.java b/functional-test/src/main/java/org/zanata/page/account/EditProfilePage.java
index f55adc9acd..addb2d5246 100644
--- a/functional-test/src/main/java/org/zanata/page/account/EditProfilePage.java
+++ b/functional-test/src/main/java/org/zanata/page/account/EditProfilePage.java
@@ -47,7 +47,7 @@ public EditProfilePage enterName(String name) {
log.info("Enter name {}", name);
waitForWebElement(nameField).clear();
waitForWebElement(nameField).sendKeys(name);
- defocus();
+ defocus(nameField);
return new EditProfilePage(getDriver());
}
@@ -62,7 +62,7 @@ public EditProfilePage enterEmail(String email) {
log.info("Enter email {}", email);
waitForWebElement(emailField).clear();
waitForWebElement(emailField).sendKeys(email);
- defocus();
+ defocus(emailField);
return new EditProfilePage(getDriver());
}
diff --git a/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
index 110960e899..f78fbc8d66 100644
--- a/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
+++ b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
@@ -53,7 +53,7 @@ public class RegisterPage extends CorePage {
private By nameField = By.id("loginForm:name");
private By emailField = By.id("loginForm:emailField:email");
- private By usernameField = By.id("loginForm:usernameField:username");
+ public By usernameField = By.id("loginForm:usernameField:username");
private By passwordField = By.id("loginForm:passwordField:password");
private By signUpButton = By.xpath("//input[@value='Sign Up']");
private By showHideToggleButton = By.className("js-form-password-toggle");
diff --git a/functional-test/src/main/java/org/zanata/page/dashboard/DashboardBasePage.java b/functional-test/src/main/java/org/zanata/page/dashboard/DashboardBasePage.java
index e2a89fb94c..9f3c672763 100644
--- a/functional-test/src/main/java/org/zanata/page/dashboard/DashboardBasePage.java
+++ b/functional-test/src/main/java/org/zanata/page/dashboard/DashboardBasePage.java
@@ -35,6 +35,11 @@ public class DashboardBasePage extends BasePage {
private By activityTab = By.id("activity_tab");
private By projectsTab = By.id("projects_tab");
private By settingsTab = By.id("settings_tab");
+
+ private By activityTabBody = By.id("activity");
+ private By projectsTabBody = By.id("projects");
+ private By settingsTabBody = By.id("settings");
+
private By settingsAccountTab = By.id("account_tab");
private By settingsProfileTab = By.id("profile_tab");
private By settingsClientTab = By.id("client_tab");
@@ -62,6 +67,7 @@ public String getUserFullName() {
public DashboardActivityTab gotoActivityTab() {
log.info("Click Activity tab");
+ waitForElementExists(activityTabBody);
clickWhenTabEnabled(waitForWebElement(activityTab));
return new DashboardActivityTab(getDriver());
}
@@ -75,12 +81,14 @@ public boolean activityTabIsSelected() {
public DashboardProjectsTab gotoProjectsTab() {
log.info("Click Projects tab");
+ waitForElementExists(projectsTabBody);
clickWhenTabEnabled(waitForWebElement(projectsTab));
return new DashboardProjectsTab(getDriver());
}
public DashboardBasePage goToSettingsTab() {
log.info("Click Settings tab");
+ waitForElementExists(settingsTabBody);
clickWhenTabEnabled(waitForWebElement(settingsTab));
return new DashboardBasePage(getDriver());
}
diff --git a/functional-test/src/main/java/org/zanata/page/groups/CreateVersionGroupPage.java b/functional-test/src/main/java/org/zanata/page/groups/CreateVersionGroupPage.java
index 1d972aa49c..cda863f4eb 100644
--- a/functional-test/src/main/java/org/zanata/page/groups/CreateVersionGroupPage.java
+++ b/functional-test/src/main/java/org/zanata/page/groups/CreateVersionGroupPage.java
@@ -42,7 +42,7 @@ public class CreateVersionGroupPage extends BasePage {
"letters, numbers, periods, underscores and hyphens.";
private By groupIdField = By.id("group-form:slugField:slug");
- private By groupNameField = By.id("group-form:nameField:name");
+ public By groupNameField = By.id("group-form:nameField:name");
private By groupDescriptionField = By.id("group-form:descriptionField:description");
private By saveButton = By.id("group-form:group-create-new");
private By createNewButton = By.id("group-form:group-create-new");
diff --git a/functional-test/src/main/java/org/zanata/page/groups/VersionGroupPage.java b/functional-test/src/main/java/org/zanata/page/groups/VersionGroupPage.java
index 2473f3b491..015a3837a5 100644
--- a/functional-test/src/main/java/org/zanata/page/groups/VersionGroupPage.java
+++ b/functional-test/src/main/java/org/zanata/page/groups/VersionGroupPage.java
@@ -57,6 +57,12 @@ public class VersionGroupPage extends BasePage {
private By projectsTab = By.id("projects_tab");
private By maintainersTab = By.id("maintainers_tab");
private By settingsTab = By.id("settings_tab");
+
+ private By languagesTabBody = By.id("languages");
+ private By projectsTabBody = By.id("projects");
+ private By maintainersTabBody = By.id("maintainers");
+ private By settingsTabBody = By.id("settings");
+
private By settingsLanguagesTab = By.id("settings-languages_tab");
public VersionGroupPage(final WebDriver driver) {
@@ -146,10 +152,6 @@ public VersionLanguagesPage clickOnProjectVersionLinkOnRow(int row) {
return new VersionLanguagesPage(getDriver());
}
- public void clickOnTab(String tabId) {
- waitForWebElement(By.id(tabId)).click();
- }
-
public VersionGroupPage clickAddProjectVersionsButton() {
log.info("Click Add Project Version");
// parent
@@ -160,24 +162,28 @@ public VersionGroupPage clickAddProjectVersionsButton() {
public VersionGroupPage clickLanguagesTab() {
log.info("Click Languages tab");
+ waitForElementExists(languagesTabBody);
clickWhenTabEnabled(waitForWebElement(languagesTab));
return new VersionGroupPage(getDriver());
}
public VersionGroupPage clickProjectsTab() {
log.info("Click Projects tab");
+ waitForElementExists(projectsTabBody);
clickWhenTabEnabled(waitForWebElement(projectsTab));
return new VersionGroupPage(getDriver());
}
public VersionGroupPage clickMaintainersTab() {
log.info("Click Maintainers tab");
+ waitForElementExists(maintainersTabBody);
clickWhenTabEnabled(waitForWebElement(maintainersTab));
return new VersionGroupPage(getDriver());
}
public VersionGroupPage clickSettingsTab() {
log.info("Click Settings tab");
+ waitForElementExists(settingsTabBody);
clickWhenTabEnabled(waitForWebElement(settingsTab));
return new VersionGroupPage(getDriver());
}
diff --git a/functional-test/src/main/java/org/zanata/page/projects/ProjectBasePage.java b/functional-test/src/main/java/org/zanata/page/projects/ProjectBasePage.java
index 7ad056b2e8..e8a8cd52e9 100644
--- a/functional-test/src/main/java/org/zanata/page/projects/ProjectBasePage.java
+++ b/functional-test/src/main/java/org/zanata/page/projects/ProjectBasePage.java
@@ -44,6 +44,12 @@ public class ProjectBasePage extends BasePage {
private By maintainersTab = By.id("maintainers_tab");
private By aboutTab = By.id("about_tab");
private By settingsTab = By.id("settings_tab");
+
+ private By versionsTabBody = By.id("versions");
+ private By maintainersTabBody = By.id("maintainers");
+ private By aboutTabBody = By.id("about");
+ private By settingsTabBody = By.id("settings");
+
private By settingsGeneralTab = By.id("settings-general_tab");
private By settingsPermissionTab = By.id("settings-permissions_tab");
private By settingsTranslationTab = By.id("settings-translation_tab");
@@ -65,6 +71,7 @@ public String getProjectName() {
public ProjectVersionsPage gotoVersionsTab() {
log.info("Click Versions tab");
+ waitForElementExists(versionsTabBody);
clickWhenTabEnabled(waitForWebElement(versionsTab));
waitForWebElement(By.id("versions"));
return new ProjectVersionsPage(getDriver());
@@ -72,6 +79,7 @@ public ProjectVersionsPage gotoVersionsTab() {
public ProjectMaintainersPage gotoMaintainersTab() {
log.info("Click Maintainers tab");
+ waitForElementExists(maintainersTabBody);
clickWhenTabEnabled(waitForWebElement(maintainersTab));
waitForWebElement(By.id("maintainers"));
return new ProjectMaintainersPage(getDriver());
@@ -79,6 +87,7 @@ public ProjectMaintainersPage gotoMaintainersTab() {
public ProjectAboutPage gotoAboutTab() {
log.info("Click About tab");
+ waitForElementExists(aboutTabBody);
clickWhenTabEnabled(waitForWebElement(aboutTab));
waitForWebElement(By.id("about"));
return new ProjectAboutPage(getDriver());
@@ -91,6 +100,7 @@ public boolean settingsTabIsDisplayed() {
public ProjectBasePage gotoSettingsTab() {
log.info("Click Settings tab");
+ waitForElementExists(settingsTabBody);
clickWhenTabEnabled(waitForWebElement(settingsTab));
waitForWebElement(settingsTab);
return new ProjectBasePage(getDriver());
diff --git a/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectGeneralTab.java b/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectGeneralTab.java
index f483080652..f5889d847f 100644
--- a/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectGeneralTab.java
+++ b/functional-test/src/main/java/org/zanata/page/projects/projectsettings/ProjectGeneralTab.java
@@ -73,7 +73,7 @@ public ProjectGeneralTab enterProjectName(final String projectName) {
log.info("Enter project name {}", projectName);
waitForWebElement(projectNameField).clear();
waitForWebElement(projectNameField).sendKeys(projectName);
- defocus();
+ defocus(projectNameField);
return new ProjectGeneralTab(getDriver());
}
@@ -86,7 +86,7 @@ public ProjectGeneralTab enterDescription(String projectDescription) {
log.info("Enter project description {}", projectDescription);
waitForWebElement(descriptionField).clear();
waitForWebElement(descriptionField).sendKeys(projectDescription);
- defocus();
+ defocus(descriptionField);
return new ProjectGeneralTab(getDriver());
}
diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java b/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java
index 77f521b454..0c5a880253 100644
--- a/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java
+++ b/functional-test/src/main/java/org/zanata/page/projectversion/CreateVersionPage.java
@@ -37,7 +37,7 @@ public class CreateVersionPage extends BasePage {
"must start and end with letter or number, and contain only " +
"letters, numbers, periods, underscores and hyphens.";
- private By projectVersionID = By.id("create-version-form:slugField:slug");
+ public By projectVersionID = By.id("create-version-form:slugField:slug");
private By projectTypeSelection = By.id("create-version-form:project-type");
private By saveButton = By.id("create-version-form:button-create");
private By copyFromPreviousVersionChk = By.id("create-version-form:copy-from-version");
diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/VersionBasePage.java b/functional-test/src/main/java/org/zanata/page/projectversion/VersionBasePage.java
index f8addd8514..102166ca6b 100644
--- a/functional-test/src/main/java/org/zanata/page/projectversion/VersionBasePage.java
+++ b/functional-test/src/main/java/org/zanata/page/projectversion/VersionBasePage.java
@@ -33,13 +33,18 @@
@Slf4j
public class VersionBasePage extends BasePage {
- private By settingsTab = By.id("settings_tab");
private By settingsGeneralTab = By.id("settings-general_tab");
private By settingsLanguagesTab = By.id("settings-languages_tab");
private By settingsDocumentsTab = By.id("settings-documents_tab");
private By settingsTranslationTab = By.id("settings-translation_tab");
- private By documentsTab = By.id("documents");
- private By languageTab = By.id("languages");
+ private By documentsTab = By.id("documents_tab");
+ private By languageTab = By.id("languages_tab");
+ private By settingsTab = By.id("settings_tab");
+
+ private By documentsTabBody = By.id("documents");
+ private By languageTabBody = By.id("languages");
+ private By settingsTabBody = By.id("settings");
+
private By versionInfo = By.id("version-info");
private By versionPage = By.id("version-page");
@@ -63,14 +68,16 @@ public ProjectVersionsPage clickProjectLink(String projectName) {
public VersionDocumentsPage gotoDocumentTab() {
log.info("Click Documents tab");
- clickWhenTabEnabled(waitForWebElement(By.id("documents_tab")));
+ waitForElementExists(documentsTabBody);
+ clickWhenTabEnabled(waitForWebElement(documentsTab));
waitForWebElement(By.id("documents"));
return new VersionDocumentsPage(getDriver());
}
public VersionLanguagesPage gotoLanguageTab() {
log.info("Click Languages tab");
- clickWhenTabEnabled(waitForWebElement(By.id("languages_tab")));
+ waitForElementExists(languageTabBody);
+ clickWhenTabEnabled(waitForWebElement(languageTab));
waitForWebElement(By.id("languages"));
return new VersionLanguagesPage(getDriver());
}
@@ -78,8 +85,9 @@ public VersionLanguagesPage gotoLanguageTab() {
public VersionBasePage gotoSettingsTab() {
log.info("Click Settings tab");
slightPause();
- clickWhenTabEnabled(waitForWebElement(By.id("settings_tab")));
- waitForWebElement(By.id("settings"));
+ waitForElementExists(settingsTabBody);
+ clickWhenTabEnabled(waitForWebElement(settingsTab));
+ waitForWebElement(settingsTabBody);
return new VersionBasePage(getDriver());
}
diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/VersionDocumentsPage.java b/functional-test/src/main/java/org/zanata/page/projectversion/VersionDocumentsPage.java
index daaf57ec13..e79c925e81 100644
--- a/functional-test/src/main/java/org/zanata/page/projectversion/VersionDocumentsPage.java
+++ b/functional-test/src/main/java/org/zanata/page/projectversion/VersionDocumentsPage.java
@@ -65,7 +65,7 @@ public List getSourceDocumentNames() {
public List apply(WebDriver input) {
List fileNames = new ArrayList();
for (WebElement element : getDocumentsTabDocumentList()) {
- fileNames.add(waitForWebElement(element,
+ fileNames.add(element.findElement(
By.className("list__title"))
.getText());
}
diff --git a/functional-test/src/main/java/org/zanata/page/projectversion/VersionLanguagesPage.java b/functional-test/src/main/java/org/zanata/page/projectversion/VersionLanguagesPage.java
index 1e357a71b7..c4326c978f 100644
--- a/functional-test/src/main/java/org/zanata/page/projectversion/VersionLanguagesPage.java
+++ b/functional-test/src/main/java/org/zanata/page/projectversion/VersionLanguagesPage.java
@@ -58,8 +58,8 @@ private List getLanguageTabLocaleList() {
private List getLanguageTabDocumentList() {
log.info("Query documents list");
- return waitForWebElement(languageDocumentList)
- .findElement(By.className("list--stats"))
+ return waitForWebElement(waitForElementExists(languageDocumentList),
+ By.className("list--stats"))
.findElements(documentListItem);
}
diff --git a/functional-test/src/main/java/org/zanata/page/webtrans/EditorPage.java b/functional-test/src/main/java/org/zanata/page/webtrans/EditorPage.java
index 7b42b7241f..5185878ecf 100644
--- a/functional-test/src/main/java/org/zanata/page/webtrans/EditorPage.java
+++ b/functional-test/src/main/java/org/zanata/page/webtrans/EditorPage.java
@@ -94,6 +94,16 @@ public boolean apply(WebDriver input) {
return new EditorPage(getDriver());
}
+ /**
+ * There is usually a long poll waiting for GWTEventService events
+ * from the server.
+ * @return
+ */
+ @Override
+ protected int getExpectedBackgroundRequests() {
+ return 1;
+ }
+
/**
* First row is header: SourceTerm, TargetTerm, Action, Details.
*
diff --git a/functional-test/src/main/java/org/zanata/util/WebElementUtil.java b/functional-test/src/main/java/org/zanata/util/WebElementUtil.java
index 85b67b13a9..fe45c9c23c 100644
--- a/functional-test/src/main/java/org/zanata/util/WebElementUtil.java
+++ b/functional-test/src/main/java/org/zanata/util/WebElementUtil.java
@@ -149,6 +149,7 @@ public static FluentWait waitForSeconds(WebDriver webDriver,
.withTimeout(durationInSec, SECONDS)
.pollingEvery(1, SECONDS)
.ignoring(NoSuchElementException.class,
+ // TODO is ignoring this safe?
StaleElementReferenceException.class);
}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterTest.java
index 22dcd0b2c5..a4eb239472 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterTest.java
@@ -130,7 +130,7 @@ public void usernamePreExisting() throws Exception {
RegisterPage registerPage = homePage
.goToRegistration()
.enterUserName("admin");
- registerPage.defocus();
+ registerPage.defocus(registerPage.usernameField);
assertThat(registerPage.expectError(
RegisterPage.USERNAME_UNAVAILABLE_ERROR))
diff --git a/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
index 435fc1facd..cccf6daf24 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
@@ -48,7 +48,7 @@ public void usernameCharacterValidation() throws Exception {
.goToHome()
.goToRegistration()
.enterUserName("user|name");
- registerPage.defocus();
+ registerPage.defocus(registerPage.usernameField);
assertThat(registerPage.expectError(
RegisterPage.USERNAME_VALIDATION_ERROR))
diff --git a/functional-test/src/test/java/org/zanata/feature/projectversion/CreateProjectVersionTest.java b/functional-test/src/test/java/org/zanata/feature/projectversion/CreateProjectVersionTest.java
index a6d3f7f2db..2022c74e18 100644
--- a/functional-test/src/test/java/org/zanata/feature/projectversion/CreateProjectVersionTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/projectversion/CreateProjectVersionTest.java
@@ -85,7 +85,7 @@ public void idFieldMustNotBeEmpty() throws Exception {
.goToProjectByName("about fedora")
.clickCreateVersionLink()
.inputVersionId("");
- createVersionPage.defocus();
+ createVersionPage.defocus(createVersionPage.projectVersionID);
assertThat(createVersionPage.getErrors())
.contains("value is required")
@@ -101,7 +101,7 @@ public void idStartsAndEndsWithAlphanumeric() throws Exception {
.goToProjectByName("about fedora")
.clickCreateVersionLink()
.inputVersionId("-A");
- createVersionPage.defocus();
+ createVersionPage.defocus(createVersionPage.projectVersionID);
assertThat(createVersionPage.expectError(
CreateVersionPage.VALIDATION_ERROR))
@@ -109,7 +109,7 @@ public void idStartsAndEndsWithAlphanumeric() throws Exception {
.as("The input is rejected");
createVersionPage = createVersionPage.inputVersionId("B-");
- createVersionPage.defocus();
+ createVersionPage.defocus(createVersionPage.projectVersionID);
assertThat(createVersionPage.expectError(
CreateVersionPage.VALIDATION_ERROR))
@@ -117,7 +117,7 @@ public void idStartsAndEndsWithAlphanumeric() throws Exception {
.as("The input is rejected");
createVersionPage = createVersionPage.inputVersionId("_C_");
- createVersionPage.defocus();
+ createVersionPage.defocus(createVersionPage.projectVersionID);
createVersionPage = createVersionPage.waitForNumErrors(1);
assertThat(createVersionPage.expectError(
@@ -126,7 +126,7 @@ public void idStartsAndEndsWithAlphanumeric() throws Exception {
.as("The input is rejected");
createVersionPage = createVersionPage.inputVersionId("A-B_C");
- createVersionPage.defocus();
+ createVersionPage.defocus(createVersionPage.projectVersionID);
createVersionPage = createVersionPage.waitForNumErrors(0);
assertThat(createVersionPage.getErrors())
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
index 71d9e3fb34..0919b2b7de 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
@@ -26,6 +26,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import org.openqa.selenium.By;
import org.zanata.feature.Feature;
import org.zanata.feature.testharness.ZanataTestCase;
import org.zanata.feature.testharness.TestPlan.BasicAcceptanceTest;
@@ -214,8 +215,9 @@ public void inputValidationForID() throws Exception {
CreateVersionGroupPage groupPage = versionGroupsPageBase
.createNewGroup()
.inputGroupId(inputText)
- .inputGroupName(inputText)
- .saveGroupFailure();
+ .inputGroupName(inputText);
+ groupPage.defocus(groupPage.groupNameField);
+ groupPage.saveGroupFailure();
assertThat(groupPage.expectError(
CreateVersionGroupPage.VALIDATION_ERROR))
diff --git a/functional-test/src/test/java/org/zanata/util/HasEmailRule.java b/functional-test/src/test/java/org/zanata/util/HasEmailRule.java
index c66394fe38..cb8528a497 100644
--- a/functional-test/src/test/java/org/zanata/util/HasEmailRule.java
+++ b/functional-test/src/test/java/org/zanata/util/HasEmailRule.java
@@ -27,6 +27,7 @@
import javax.mail.internet.MimeMultipart;
+import org.junit.rules.ExternalResource;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -41,29 +42,25 @@
* pahuang@redhat.com
*/
@Slf4j
-public class HasEmailRule implements TestRule {
- private static final Wiser wiser;
+public class HasEmailRule extends ExternalResource {
+ private volatile static Wiser wiser;
- static {
- String port = PropertiesHolder.getProperty("smtp.port");
- wiser = new Wiser(Integer.parseInt(port));
- wiser.start();
- // NB we never call wiser.stop() because we want the email
- // server to stay running for all tests
+ @Override
+ protected void before() throws Throwable {
+ super.before();
+ if (HasEmailRule.wiser == null) {
+ String port = PropertiesHolder.getProperty("smtp.port");
+ HasEmailRule.wiser = new Wiser(Integer.parseInt(port));
+ HasEmailRule.wiser.start();
+ // NB we never call wiser.stop() because we want the email
+ // server to stay running for all tests in this VM
+ }
}
@Override
- public Statement apply(final Statement base, Description description) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- try {
- base.evaluate();
- } finally {
- wiser.getMessages().clear();
- }
- }
- };
+ protected void after() {
+ wiser.getMessages().clear();
+ super.after();
}
public List getMessages() {
diff --git a/functional-test/src/test/java/org/zanata/util/TestLogger.java b/functional-test/src/test/java/org/zanata/util/TestLogger.java
new file mode 100644
index 0000000000..317c055450
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/util/TestLogger.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
+ * @author tags. See the copyright.txt file in the distribution for a full
+ * listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.zanata.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * @author Sean Flanigan
+ * sflaniga@redhat.com
+ */
+@Slf4j
+public class TestLogger extends RunListener {
+ @Override
+ public void testStarted(Description description) throws Exception {
+ log.info("Test {} starting", description);
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ log.info("Test {} finished", description);
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ log.error("FAILED test " + failure, failure.getException());
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ log.error("FAILED ASSUMPTION in test " + failure,
+ failure.getException());
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ log.error("Test {} IGNORED", description);
+ }
+
+}
diff --git a/functional-test/src/test/resources/conf/standalone.xml b/functional-test/src/test/resources/conf/standalone.xml
index fcab1ca581..aaccd519ea 100644
--- a/functional-test/src/test/resources/conf/standalone.xml
+++ b/functional-test/src/test/resources/conf/standalone.xml
@@ -27,6 +27,7 @@
+
diff --git a/functional-test/src/test/resources/conf/standalone_wildfly.xml b/functional-test/src/test/resources/conf/standalone_wildfly.xml
index cb2bb3595b..8a732e530b 100644
--- a/functional-test/src/test/resources/conf/standalone_wildfly.xml
+++ b/functional-test/src/test/resources/conf/standalone_wildfly.xml
@@ -27,6 +27,7 @@
+
diff --git a/pom.xml b/pom.xml
index e87ab9d684..b6455e9503 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,6 +71,11 @@
5.1.26
compile
+
+ ${project.build.directory}/cargo/installs
+
+
+