Skip to content

Commit 8f1b581

Browse files
committed
Improve synchronization of ParentEntityEditPanel
1 parent 74d19c5 commit 8f1b581

3 files changed

Lines changed: 61 additions & 43 deletions

File tree

src/org/labkey/test/Locator.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.commons.lang3.StringUtils;
2020
import org.apache.commons.lang3.mutable.MutableObject;
2121
import org.intellij.lang.annotations.Language;
22+
import org.jetbrains.annotations.Contract;
2223
import org.jetbrains.annotations.NotNull;
2324
import org.jetbrains.annotations.Nullable;
2425
import org.labkey.test.selenium.LazyWebElement;
@@ -373,11 +374,13 @@ protected static <T> T extractInputFromFluentWait(FluentWait<T> wait)
373374
return wrappedContext.getValue();
374375
}
375376

377+
@Contract(pure = true)
376378
public LazyWebElement<?> findWhenNeeded(SearchContext context)
377379
{
378380
return new LazyWebElement<>(this, context);
379381
}
380382

383+
@Contract(pure = true)
381384
public RefindingWebElement refindWhenNeeded(SearchContext context)
382385
{
383386
return new RefindingWebElement(this, context);
@@ -391,11 +394,13 @@ public WebElement findElement(SearchContext context)
391394
new NoSuchElementException("Unable to find element: " + getFindDescription(context)));
392395
}
393396

397+
@Contract(pure = true)
394398
public WebElement findElementOrNull(SearchContext context)
395399
{
396400
return findOptionalElement(context).orElse(null);
397401
}
398402

403+
@Contract(pure = true)
399404
public Optional<WebElement> findOptionalElement(SearchContext context)
400405
{
401406
List<WebElement> elements = findElements(context);
@@ -404,6 +409,7 @@ public Optional<WebElement> findOptionalElement(SearchContext context)
404409
return Optional.of(elements.get(0));
405410
}
406411

412+
@Contract(pure = true)
407413
@Override
408414
public List<WebElement> findElements(SearchContext context)
409415
{
@@ -454,11 +460,13 @@ public List<WebElement> findElements(SearchContext context)
454460
}
455461
}
456462

463+
@Contract(pure = true)
457464
public boolean existsIn(SearchContext context)
458465
{
459466
return findElementOrNull(context) != null;
460467
}
461468

469+
@Contract(pure = true)
462470
public boolean isDisplayed(SearchContext context)
463471
{
464472
WebElement element = findElementOrNull(context);
@@ -471,6 +479,7 @@ public boolean isDisplayed(SearchContext context)
471479
* @param context Search context.
472480
* @return True if there are any elements visible, false otherwise.
473481
*/
482+
@Contract(pure = true)
474483
public boolean areAnyVisible(SearchContext context)
475484
{
476485
List<WebElement> elements = findElements(context);

src/org/labkey/test/components/bootstrap/Panel.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,20 @@ public class ElementCache extends Component<?>.ElementCache
7171
protected final WebElement panelBody = Locator.byClass("panel-body").findWhenNeeded(this);
7272
}
7373

74-
public static class PanelFinder extends WebDriverComponentFinder<Panel<?>, PanelFinder>
74+
protected static abstract class AbstractPanelFinder<C extends Panel<?>, F extends AbstractPanelFinder<C, F>> extends WebDriverComponentFinder<C, F>
7575
{
76-
private final Locator.XPathLocator _baseLocator = Locator.tagWithClass("div", "panel-default");
76+
private final Locator.XPathLocator _baseLocator = Locator.tagWithClass("div", "panel");
7777
private String _title = null;
7878

79-
public PanelFinder(WebDriver driver)
79+
public AbstractPanelFinder(WebDriver driver)
8080
{
8181
super(driver);
8282
}
8383

84-
public PanelFinder withTitle(String title)
84+
public F withTitle(String title)
8585
{
8686
_title = title;
87-
return this;
88-
}
89-
90-
@Override
91-
protected Panel<?> construct(WebElement el, WebDriver driver)
92-
{
93-
return new PanelImpl(el, driver);
87+
return getThis();
9488
}
9589

9690
@Override
@@ -103,6 +97,26 @@ protected Locator locator()
10397
return _baseLocator;
10498
}
10599
}
100+
101+
public static class PanelFinder extends AbstractPanelFinder<Panel<?>, PanelFinder>
102+
{
103+
public PanelFinder(WebDriver driver)
104+
{
105+
super(driver);
106+
}
107+
108+
@Override
109+
protected PanelFinder getThis()
110+
{
111+
return this;
112+
}
113+
114+
@Override
115+
protected Panel<?> construct(WebElement el, WebDriver driver)
116+
{
117+
return new PanelImpl(el, driver);
118+
}
119+
}
106120
}
107121

108122
class PanelImpl extends Panel<ElementCache>

src/org/labkey/test/components/ui/entities/ParentEntityEditPanel.java

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44
import org.labkey.test.BootstrapLocators;
55
import org.labkey.test.Locator;
66
import org.labkey.test.WebDriverWrapper;
7-
import org.labkey.test.components.Component;
8-
import org.labkey.test.components.WebDriverComponent;
7+
import org.labkey.test.components.bootstrap.Panel;
98
import org.labkey.test.components.react.BaseReactSelect;
109
import org.labkey.test.components.react.FilteringReactSelect;
1110
import org.labkey.test.components.react.ReactSelect;
1211
import org.openqa.selenium.NoSuchElementException;
1312
import org.openqa.selenium.StaleElementReferenceException;
1413
import org.openqa.selenium.WebDriver;
1514
import org.openqa.selenium.WebElement;
15+
import org.openqa.selenium.support.ui.ExpectedConditions;
1616

1717
import java.util.Arrays;
18+
import java.util.HashSet;
1819
import java.util.List;
20+
import java.util.Set;
1921

2022
/**
2123
* <p>
@@ -25,11 +27,8 @@
2527
* </p>
2628
* @see <a href="https://github.com/LabKey/labkey-ui-components/blob/master/packages/components/src/components/entities/ParentEntityEditPanel.tsx">ParentEntityEditPanel.tsx</a>
2729
*/
28-
public class ParentEntityEditPanel extends WebDriverComponent<ParentEntityEditPanel.ElementCache>
30+
public class ParentEntityEditPanel extends Panel<ParentEntityEditPanel.ElementCache>
2931
{
30-
private final WebDriver driver;
31-
private final WebElement editingDiv;
32-
3332
/**
3433
* Constructor for the panel.
3534
*
@@ -38,20 +37,7 @@ public class ParentEntityEditPanel extends WebDriverComponent<ParentEntityEditPa
3837
*/
3938
public ParentEntityEditPanel(WebElement element, WebDriver driver)
4039
{
41-
this.driver = driver;
42-
editingDiv = element;
43-
}
44-
45-
@Override
46-
public WebElement getComponentElement()
47-
{
48-
return editingDiv;
49-
}
50-
51-
@Override
52-
protected WebDriver getDriver()
53-
{
54-
return driver;
40+
super(element, driver);
5541
}
5642

5743
@Override
@@ -184,6 +170,10 @@ public void clickSave(int waitTime)
184170
WebDriverWrapper.waitFor(()->elementCache().saveButton.isEnabled(),
185171
"Save button is not enabled.", 2_500);
186172

173+
String parentType = getTitle().split(" ", 2)[1].trim(); // Trim "Editing" from the title
174+
Set<String> selections = new HashSet<>();
175+
getAllParents().stream().map(BaseReactSelect::getSelections).forEach(selections::addAll);
176+
187177
// The wait time is used here to validate the panel exits edit mode.
188178
clickButtonWaitForPanel(elementCache().saveButton, waitTime);
189179

@@ -192,6 +182,20 @@ public void clickSave(int waitTime)
192182
WebDriverWrapper.waitFor(()->!progressbar.isDisplayed(),
193183
"It looks like an update took too long.", waitTime);
194184

185+
Panel<?> detailsPanel = new Panel.PanelFinder(getDriver()).withTitle(parentType).waitFor(getDriver());
186+
if (!selections.isEmpty())
187+
{
188+
for (String selection : selections)
189+
{
190+
getWrapper().quickWait().until(ExpectedConditions.visibilityOf(
191+
Locator.linkWithText(selection).findWhenNeeded(detailsPanel)));
192+
}
193+
}
194+
else
195+
{
196+
getWrapper().quickWait().until(ExpectedConditions.visibilityOf(
197+
Locator.tag("td").containing("has been set for this sample.").findWhenNeeded(detailsPanel)));
198+
}
195199
}
196200

197201
/**
@@ -467,28 +471,19 @@ public boolean hasParentInputError()
467471
/**
468472
* Simple finder for this panel.
469473
*/
470-
public static class ParentEntityEditPanelFinder extends WebDriverComponentFinder<ParentEntityEditPanel, ParentEntityEditPanelFinder>
474+
public static class ParentEntityEditPanelFinder extends AbstractPanelFinder<ParentEntityEditPanel, ParentEntityEditPanelFinder>
471475
{
472476
public ParentEntityEditPanelFinder(WebDriver driver)
473477
{
474478
super(driver);
479+
withTitle("Editing");
475480
}
476481

477482
@Override
478483
protected ParentEntityEditPanel construct(WebElement element, WebDriver driver)
479484
{
480485
return new ParentEntityEditPanel(element, driver);
481486
}
482-
483-
@Override
484-
protected Locator locator()
485-
{
486-
return Locator
487-
.tagContainingText("div", "Editing")
488-
.withClass("panel-heading")
489-
.parent()
490-
.child(Locator.tagWithClass("div", "panel-body"));
491-
}
492487
}
493488

494489
public static class DataClassAddParentEntityPanelFinder extends WebDriverComponentFinder<ParentEntityEditPanel, DataClassAddParentEntityPanelFinder>
@@ -517,7 +512,7 @@ protected ElementCache newElementCache()
517512
return new ElementCache();
518513
}
519514

520-
protected class ElementCache extends Component<?>.ElementCache
515+
protected class ElementCache extends Panel<?>.ElementCache
521516
{
522517
final WebElement saveButton = Locator.byClass("btn-success").withText("Save").findWhenNeeded(this);
523518
final WebElement cancelButton = Locator.byClass("btn-default").withText("Cancel").refindWhenNeeded(this);

0 commit comments

Comments
 (0)