1919import org .labkey .test .components .ui .grids .FieldReferenceManager .FieldReference ;
2020import org .labkey .test .params .FieldDefinition ;
2121import org .labkey .test .params .FieldKey ;
22+ import org .labkey .test .util .CachingSupplier ;
2223import org .labkey .test .util .selenium .ScrollUtils ;
2324import org .labkey .test .util .selenium .WebElementUtils ;
2425import org .openqa .selenium .By ;
@@ -176,55 +177,29 @@ public boolean canRemoveColumn(CharSequence columnIdentifier)
176177
177178 private boolean hasSelectColumn ()
178179 {
179- return elementCache ().selectColumn . isDisplayed ();
180+ return elementCache ().hasSelectColumn . get ();
180181 }
181182
182183 public EditableGrid selectRow (int index , boolean checked )
183184 {
184- if (hasSelectColumn ())
185- {
186- WebElement checkBox = Locator .css ("td > input[type=checkbox]" ).findElement (getRow (index ));
187- getWrapper ().setCheckbox (checkBox , checked );
188- }
189- else
190- {
191- throw new NoSuchElementException ("There is no select checkbox for row " + index );
192- }
185+ elementCache ().getCheckbox (index ).set (checked );
193186 return this ;
194187 }
195188
196189 public boolean isRowSelected (int index )
197190 {
198- if (hasSelectColumn ())
199- {
200- WebElement checkBox = Locator .css ("td > input[type=checkbox]" ).findElement (getRow (index ));
201- return checkBox .isSelected ();
202- }
203- else
204- {
205- throw new NoSuchElementException ("There is no select checkbox for row " + index );
206- }
191+ return elementCache ().getCheckbox (index ).isSelected ();
207192 }
208193
209194 public EditableGrid selectAll (boolean checked )
210195 {
211- if (hasSelectColumn ())
212- {
213- getWrapper ().setCheckbox (elementCache ().selectColumn , checked );
214- }
215- else
216- {
217- throw new NoSuchElementException ("There is no select checkbox for all rows." );
218- }
196+ elementCache ().selectAllCheckbox .set (checked );
219197 return this ;
220198 }
221199
222200 public boolean areAllRowsSelected ()
223201 {
224- if (hasSelectColumn ())
225- return new Checkbox (elementCache ().selectColumn ).isSelected ();
226- else
227- throw new NoSuchElementException ("There is no select checkbox for all rows." );
202+ return elementCache ().selectAllCheckbox .isSelected ();
228203 }
229204
230205 /**
@@ -237,26 +212,22 @@ public boolean areAllRowsSelected()
237212 public EditableGrid shiftSelectRange (int start , int end )
238213 {
239214 if (!hasSelectColumn ())
240- throw new NoSuchElementException ("there is no select checkbox for all rows " );
215+ throw new NoSuchElementException ("there is no selection column for grid " );
241216
242217 var checkBoxes = Locator .tag ("tr" ).child ("td" )
243218 .child (Locator .tagWithAttribute ("input" , "type" , "checkbox" ))
244219 .findElements (elementCache ().table );
245- getWrapper ().scrollIntoView (checkBoxes .get (0 ), true ); // bring as much of the grid into view as possible
220+ getWrapper ().scrollIntoView (checkBoxes .get (start )); // Make sure the header isn't in the way
221+ checkBoxes .get (start ).click ();
222+ getWrapper ().scrollIntoView (checkBoxes .get (end )); // Actions.click() doesn't scroll
246223 new Actions (getDriver ())
247- .click (checkBoxes .get (start ))
248224 .keyDown (Keys .SHIFT )
249225 .click (checkBoxes .get (end ))
250226 .keyUp (Keys .SHIFT )
251227 .perform ();
252228 return this ;
253229 }
254230
255- private List <WebElement > getRows ()
256- {
257- return Locators .rows .findElements (elementCache ().table );
258- }
259-
260231 /**
261232 * @param columnIdentifiers fieldKeys, names, or labels of columns
262233 * @return grid data for the specified columns, keyed by column label
@@ -316,7 +287,7 @@ private <T> List<Map<T, String>> getGridData(Function<FieldReferenceManager.Fiel
316287 }
317288 }
318289
319- for (WebElement row : getRows ())
290+ for (WebElement row : elementCache (). getRows ())
320291 {
321292 List <WebElement > cells = row .findElements (By .tagName ("td" ));
322293 Map <T , String > rowMap = new LinkedHashMap <>(includedColHeaders .size ());
@@ -362,7 +333,7 @@ public List<String> getColumnData(CharSequence columnIdentifier)
362333
363334 private WebElement getRow (int index )
364335 {
365- return getRows ().get (index );
336+ return elementCache (). getRows ().get (index );
366337 }
367338
368339 /**
@@ -412,7 +383,7 @@ public boolean isCellReadOnly(int row, CharSequence columnIdentifier)
412383
413384 public int getRowCount ()
414385 {
415- return getRows ().size ();
386+ return elementCache (). getRows ().size ();
416387 }
417388
418389 /**
@@ -682,6 +653,7 @@ public WebElement activateCellUsingDoubleClick(int row, CharSequence columnIdent
682653 // Account for the cell already being active.
683654 if (!textArea .isDisplayed ())
684655 {
656+ getWrapper ().scrollIntoView (gridCell );
685657 getWrapper ().doubleClick (gridCell );
686658 waitFor (textArea ::isDisplayed ,
687659 String .format ("Table cell for row %d and column '%s' was not activated." , row , columnIdentifier ), 1_000 );
@@ -1111,7 +1083,7 @@ private boolean areAllInSelection()
11111083 List <String > columns = getColumnLabels ();
11121084 int selectIndexOffset = hasSelectColumn () ? 1 : 0 ;
11131085 WebElement indexCell = getCell (0 , columns .get (1 + selectIndexOffset ));
1114- WebElement endCell = getCell (getRows ().size ()-1 , columns .get (columns .size ()-1 ));
1086+ WebElement endCell = getCell (elementCache (). getRows ().size ()-1 , columns .get (columns .size ()-1 ));
11151087 return (isInSelection (indexCell ) && isInSelection (endCell ));
11161088 }
11171089
@@ -1244,7 +1216,13 @@ protected class ElementCache extends Component<?>.ElementCache
12441216 final WebElement deleteRowsBtn = Locator .byClass ("bulk-remove-button" ).findWhenNeeded (topControls );
12451217 final ExportMenu exportMenu = ExportMenu .finder (getDriver ()).findWhenNeeded (topControls );
12461218 final WebElement table = Locator .byClass ("table-cellular" ).findWhenNeeded (this );
1247- private final WebElement selectColumn = Locator .xpath ("//th/input[@type='checkbox']" ).findWhenNeeded (table );
1219+ private final Checkbox selectAllCheckbox = new Checkbox (Locator .xpath ("//th/input[@type='checkbox']" ).findWhenNeeded (table ));
1220+ private final CachingSupplier <Boolean > hasSelectColumn = new CachingSupplier <>(selectAllCheckbox ::isDisplayed );
1221+
1222+ Checkbox getCheckbox (int rowIndex )
1223+ {
1224+ return new Checkbox (Locator .css ("td > input[type=checkbox]" ).findElement (getRow (rowIndex )));
1225+ }
12481226
12491227 protected WebElement getColumnHeaderCell (CharSequence columnIdentifier )
12501228 {
@@ -1317,6 +1295,11 @@ public ReactDateTimePicker datePicker()
13171295 final WebElement addRowsPanel = Locator .byClass ("editable-grid__controls" ).findWhenNeeded (this );
13181296 final Input addCountInput = Input .Input (Locator .name ("addCount" ), getDriver ()).findWhenNeeded (addRowsPanel );
13191297 final WebElement addRowsButton = Locator .byClass ("btn-primary" ).findWhenNeeded (addRowsPanel );
1298+
1299+ List <WebElement > getRows ()
1300+ {
1301+ return Locators .rows .findElements (table );
1302+ }
13201303 }
13211304
13221305 protected abstract static class Locators
0 commit comments