Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.labkey.test.components.Component;
import org.labkey.test.components.WebDriverComponent;
import org.labkey.test.util.TestLogger;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
Expand Down Expand Up @@ -191,20 +193,44 @@ public String getViewLinkText()
public void clickViewLink()
{
String currentUrl = getDriver().getCurrentUrl().toLowerCase();
String targetUrl = elementCache().link.getAttribute("href").toLowerCase();

TestLogger.log(String.format("ServerNotificationItem.clickViewLink: currentUrl: %s", currentUrl));
TestLogger.log(String.format("ServerNotificationItem.clickViewLink: targetUrl: %s", targetUrl));

elementCache().link.click();
// A notification refresh can re-render, reorder, or briefly remove the list, so pin the link by href and retry.
String href = WebDriverWrapper.waitFor(() -> {
try
{
return elementCache().link.getDomAttribute("href");
}
catch (StaleElementReferenceException | NoSuchElementException retry)
{
return null;
}
}, "The notification has no 'View' link.", WebDriverWrapper.WAIT_FOR_JAVASCRIPT);

Locator.XPathLocator linkLocator = Locator.tagWithClass("ul", "server-notifications-listing")
.descendant(Locator.tagWithAttribute("a", "href", href));
String targetUrl = WebDriverWrapper.waitFor(() -> {
try
{
WebElement link = linkLocator.findElement(getDriver());
String url = link.getAttribute("href").toLowerCase();
link.click();
return url;
}
catch (StaleElementReferenceException | NoSuchElementException retry)
{
return null;
}
}, "The 'View' link in the notification did not become clickable.", WebDriverWrapper.WAIT_FOR_JAVASCRIPT);

TestLogger.log(String.format("ServerNotificationItem.clickViewLink: targetUrl: %s", targetUrl));

// If the url before clicking the link is the same as the target then don't wait for a navigation.
if(!targetUrl.equalsIgnoreCase(currentUrl))
if (!targetUrl.equalsIgnoreCase(currentUrl))
{
WebDriverWrapper.waitFor(()->!getDriver().getCurrentUrl().equalsIgnoreCase(currentUrl),
"Clicking the 'View' link in the notification did not navigate in time.", 5_000);
}

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,7 @@ public ImportsPage clickViewAll()
*/
private WebElement waitForNotificationList()
{

expand();

// Wait for the listing container to show up. The listing container is in the open menu, scope the search to that.
Locator notificationsContainerLocator = Locator.tagWithClass("div", "server-notifications-listing-container");
WebDriverWrapper.waitFor(()-> notificationsContainerLocator.areAnyVisible(elementCache().menuContent()),
"List container did not render.", 500);

// Find again (lambda requires a final reference to the component).
WebElement listContainer = notificationsContainerLocator.refindWhenNeeded(elementCache().menuContent());

// It may be a moment before any notifications show up.
WebDriverWrapper.waitFor(()-> Locator.tagWithClass("ul", "server-notifications-listing").areAnyVisible(listContainer),
"There are no notifications in the drop down.", 1_000);
waitForListingVisible();

// Just wait for a moment in case the list is slow to update with the most recent notification.
WebDriverWrapper.sleep(500);
Expand All @@ -218,10 +205,28 @@ private WebElement waitForNotificationList()
// is no guarantee that it contains the most recent message. For example if an import is in progress a message
// will appear in the list saying as much. When the import is done the 'in progress' message will go away and
// be replaced with a new 'complete' message.
waitForListingVisible();

// Find the container again, don't return listContainer WebElement previously found. If the list was slow to
// update with the most recent notification the old reference will be stale.
return notificationsContainerLocator.refindWhenNeeded((elementCache().menuContent()));
return LISTING_CONTAINER.refindWhenNeeded(elementCache().menuContent());
}

private static final Locator.XPathLocator LISTING_CONTAINER = Locator.tagWithClass("div", "server-notifications-listing-container");

private void waitForListingVisible()
{
// Every notification refresh swaps the listing for a spinner until the reload finishes, so re-find on each poll.
WebDriverWrapper.waitFor(() -> {
try
{
expand();
return LISTING_CONTAINER.child(Locator.tagWithClass("ul", "server-notifications-listing"))
.areAnyVisible(elementCache().menuContent());
}
catch (StaleElementReferenceException | NoSuchElementException retry)
{
return false;
}
}, "There are no notifications in the drop down.", WebDriverWrapper.WAIT_FOR_JAVASCRIPT);
}

/**
Expand Down
Loading