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
13 changes: 4 additions & 9 deletions src/org/labkey/test/components/dumbster/EmailRecordTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class EmailRecordTable extends Table

public EmailRecordTable(WebDriver driver)
{
super(driver, new RefindingWebElement(gridLocator, driver).withTimeout(WAIT_FOR_JAVASCRIPT));
super(driver, new RefindingWebElement(gridLocator, driver).withTimeout(WAIT_FOR_JAVASCRIPT), _headerRows);
((RefindingWebElement) getComponentElement()).withRefindListener(el -> clearElementCache());
}

Expand All @@ -67,7 +67,7 @@ public int getColumnIndex(String headerLabel)
}
catch (IllegalArgumentException fallback)
{
return super.getColumnIndex(headerLabel, _headerRows);
return super.getColumnIndex(headerLabel);
}
}

Expand Down Expand Up @@ -171,7 +171,7 @@ public List<EmailMessage> getMessagesByHeaderAndText(String header, String text)

public List<Integer> getTableIndexesWhereTextAppears(String header, String text)
{
List<String> columnText = getColumnAsText(header, _headerRows);
List<String> columnText = getColumnAsText(header);
List<Integer> colsWithString = new ArrayList<>();
for(int i = 1; i <= columnText.size(); i++)
{
Expand Down Expand Up @@ -231,12 +231,7 @@ private void parseViewCell(EmailMessage emailMessage)

public List<String> getColumnDataAsText(String column)
{
return getColumnAsText(column , _headerRows);
}

public int getHeaderRowCount()
{
return _headerRows;
return getColumnAsText(column);
}

public static class EmailMessage
Expand Down
65 changes: 18 additions & 47 deletions src/org/labkey/test/components/html/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@ public class Table extends WebDriverComponent<Table.Elements>
{
private final WebDriver _driver;
private final WebElement _componentElement;
private final int _bodyHeaderRowIndex; // '0' indicates that the table uses a 'thead'

public Table(WebDriver driver, WebElement componentElement)
public Table(WebDriver driver, WebElement componentElement, int headerIndex)
{
_componentElement = componentElement;
_driver = driver;
_bodyHeaderRowIndex = headerIndex;
}

public Table(WebDriver driver, WebElement componentElement)
{
this(driver, componentElement, 1);
}

public Table(WebDriverWrapper driverWrapper, WebElement componentElement)
Expand Down Expand Up @@ -141,45 +148,35 @@ public List<String> getTableHeaderColumnData(String headerText)
{
List<String> columnData = new ArrayList<>();
int columnIndex = getTableHeaderIndex(headerText);
for(int i = 1; i <= getRowCount(); i++)
for(int i = _bodyHeaderRowIndex; i <= getRowCount(); i++)
columnData.add(Locator.xpath("//tbody//tr[" + i + "]/td[" + columnIndex + "]").findElement(getDriver()).getText());
return columnData;
}

public List<String> getColumnHeaders(int headerRow)
public List<String> getColumnHeaders()
{
List<WebElement> headerEls = getColumnHeaderElements(headerRow);
List<WebElement> headerEls = getColumnHeaderElements();
List<String> columnHeaders = new ArrayList<>();
for(WebElement headerEl : headerEls){columnHeaders.add(headerEl.getText());}
return columnHeaders;
}

// TODO: This finder makes an assumption that the column headers will be in a tr in the tbody, that is not always the case.
// Maybe a possible solution would be to remove "./tbody" from the locator, but that is a thread I am not willing to pull at this time.
private List<WebElement> getColumnHeaderElements(int headerRow)
{
return getComponentElement().findElements(By.xpath("./tbody/tr["+ headerRow +"]/*[(name()='TH' or name()='TD' or name()='th' or name()='td')]"));
}

public List<WebElement> getColumnHeaderElements()
{
return getColumnHeaderElements(1);
return getComponentElement().findElements(By.xpath("./tbody/tr["+ _bodyHeaderRowIndex +"]/*[(name()='TH' or name()='TD' or name()='th' or name()='td')]"));
}

public List<WebElement> getColumnHeaderElementsByTag()
{
return getComponentElement().findElements(By.xpath(".//tr/th"));
}

protected int getColumnIndex(String headerLabel, int headerIndex)
{
//List is zero based, locators that are going to depend on this are 1
return getColumnHeaders(headerIndex).indexOf(headerLabel) + 1;
}

public int getColumnIndex(String headerLabel)
{
return getColumnIndex(headerLabel, 1);
//List is zero based, locators that are going to depend on this are 1
return getColumnHeaders().indexOf(headerLabel) + 1;
}

public String getDataAsText(int row, int col)
Expand Down Expand Up @@ -215,9 +212,9 @@ public WebElement getDataAsElement(int row, int column)
return _getDataAsElement(row, column);
}

public List<String> getColumnAsText(int col, int headerIndex)
public List<String> getColumnAsText(int col)
{
List<WebElement> columnElements = getColumnAsElement(col, headerIndex);
List<WebElement> columnElements = getColumnAsElement(col);
List<String> columnText = new ArrayList<>();

if (columnElements.size() > 0)
Expand All @@ -233,12 +230,7 @@ public List<String> getColumnAsText(int col, int headerIndex)

public List<String> getColumnAsText(String col)
{
return getColumnAsText(getColumnIndex(col), 1);
}

public List<String> getColumnAsText(String col, int colIndex)
{
return getColumnAsText(getColumnIndex(col, colIndex), colIndex);
return getColumnAsText(getColumnIndex(col));
}

public List<String> getRowAsText(int row)
Expand All @@ -247,29 +239,13 @@ public List<String> getRowAsText(int row)
return getWrapper().getTexts(cells);
}

public List<WebElement> getColumnAsElement(String name, int columnIndex)
{
int col = getColumnIndex(name, columnIndex);
return getColumnAsElement(col);
}

public List<WebElement> getColumnAsElement(String name)
{
return getColumnAsElement(name, 1);
}

public List<WebElement> getColumnAsElement(int col)
{
return getColumnAsElement(col,1);
}

public List<WebElement> getColumnAsElement(int col, int headerIndex)
{
int rowCount = getRowCount();
List<WebElement> columnElements = new ArrayList<>();
if (rowCount > 0)
{
for (int row = headerIndex + 1; row < rowCount; row++)
for (int row = _bodyHeaderRowIndex + 1; row <= rowCount; row++)
{
columnElements.add(getDataAsElement(row, col));
}
Expand All @@ -278,11 +254,6 @@ public List<WebElement> getColumnAsElement(int col, int headerIndex)
return columnElements;
}

public int getRowIndex(String columnLabel, String value, int headerIndex)
{
return getRowIndex(getColumnIndex(columnLabel, headerIndex), value);
}

public int getRowIndex(String columnLabel, String value)
{
return getRowIndex(getColumnIndex(columnLabel), value);
Expand Down
143 changes: 143 additions & 0 deletions src/org/labkey/test/pages/admin/ExternalSourcesPage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.labkey.test.pages.admin;

import org.labkey.test.Locator;
import org.labkey.test.WebDriverWrapper;
import org.labkey.test.WebTestHelper;
import org.labkey.test.components.html.Input;
import org.labkey.test.components.html.OptionSelect;
import org.labkey.test.components.html.Table;
import org.labkey.test.pages.LabKeyPage;
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.LoggedParam;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
* Wraps `AdminController.ExternalSourceAction`
*/
public class ExternalSourcesPage extends LabKeyPage<ExternalSourcesPage.ElementCache>
{
public ExternalSourcesPage(WebDriver driver)
{
super(driver);
}

public static ExternalSourcesPage beginAt(WebDriverWrapper webDriverWrapper)
{
webDriverWrapper.beginAt(WebTestHelper.buildURL("admin", "externalSources"));
return new ExternalSourcesPage(webDriverWrapper.getDriver());
}

@LogMethod
public ExternalSourcesPage ensureHost(Directive directive, String host)
{
if (!getExistingHosts().getOrDefault(directive, Collections.emptyList()).contains(host))
{
return addHost(directive, host);
}
else
{
log("Host for CSP " + directive.getDirectiveId() + " already registered: " + host);
return this;
}
}

@LogMethod (quiet = true)
public ExternalSourcesPage addHost(@LoggedParam Directive directive, @LoggedParam String host)
{
elementCache().directiveSelect.selectOption(directive);
elementCache().hostInput.set(host);

clickAndWait(elementCache().addButton);
clearCache();
return this;
}

public Map<Directive, List<String>> getExistingHosts()
{
Map<Directive, List<String>> existingHosts = new HashMap<>();

for (Map.Entry<Directive, List<Input>> entry : getExistingHostInputs().entrySet())
{
existingHosts.put(entry.getKey(), entry.getValue().stream().map(Input::getValue).toList());
}

return existingHosts;
}

public Map<Directive, List<Input>> getExistingHostInputs()
{
List<WebElement> directiveColumn = elementCache().existingValuesTable.getColumnAsElement(1);
List<WebElement> hostsColumn = elementCache().existingValuesTable.getColumnAsElement(2);

Map<Directive, List<Input>> existingHosts = new HashMap<>();

for (int i = 0; i < hostsColumn.size(); i++)
{
WebElement directiveInput = Locator.tag("input").findElement(directiveColumn.get(i));
Directive directive = Directive.valueOf(directiveInput.getDomAttribute("data-directive"));
Input hostInput = Input.Input(Locator.tag("input"), getDriver()).find(hostsColumn.get(i));
existingHosts.computeIfAbsent(directive, d -> new ArrayList<>()).add(hostInput);
}

return existingHosts;
}

@Override
protected ElementCache newElementCache()
{
return new ElementCache();
}

protected class ElementCache extends LabKeyPage<ElementCache>.ElementCache
{
final WebElement addHostForm = Locator.name("addNewHost").findWhenNeeded(this);
final OptionSelect<Directive> directiveSelect = OptionSelect.finder(Locator.id("newDirective"), Directive.class).findWhenNeeded(addHostForm);
final Input hostInput = Input.Input(Locator.id("newHostTextField"), getDriver()).findWhenNeeded(addHostForm);
final WebElement addButton = Locator.lkButton("Add").findWhenNeeded(addHostForm);

final WebElement existingValuesForm = Locator.name("existingValues").findWhenNeeded(this);
final Table existingValuesTable = new Table(getDriver(), Locator.byClass("labkey-data-region-legacy").findWhenNeeded(existingValuesForm), 0);
}

public enum Directive implements OptionSelect.SelectOption
{
Connection("connect-src"),
Font("font-src"),
Frame("frame-src"),
Image("image-src"),
Style("style-src"),
;

private final String directiveId;

Directive(String directiveId)
{
this.directiveId = directiveId;
}

public String getDirectiveId()
{
return directiveId;
}

@Override
public String getValue()
{
return name();
}

public static Directive fromId(String directiveId)
{
return Stream.of(values()).filter(d -> d.getDirectiveId().equals(directiveId)).findAny()
.orElseThrow(() -> new IllegalArgumentException("Unknown CSP directive: " + directiveId));
}
}
}
12 changes: 9 additions & 3 deletions src/org/labkey/test/tests/wiki/WikiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.labkey.test.Locator;
import org.labkey.test.categories.Daily;
import org.labkey.test.categories.Wiki;
import org.labkey.test.pages.admin.ExternalSourcesPage;
import org.labkey.test.pages.admin.ExternalSourcesPage.Directive;
import org.labkey.test.pages.search.SearchResultsPage;
import org.labkey.test.pages.wiki.EditPage;
import org.labkey.test.util.DataRegionTable;
Expand Down Expand Up @@ -159,13 +161,17 @@ public void testSteps()
@Test
public void testEmbeddedVideoInWiki()
{
String videoHost = "https://www.youtube.com";
String videoUrl = videoHost + "/embed/JEE4807UHN4";
String wikiName = "Wiki with video";
String wikiTitle = "Sample finder video";
String wikiContent = """
Some random content start : Have fun watching video below
{video:https://www.youtube.com/embed/JEE4807UHN4|height:350|width:500}
{video:%s|height:350|width:500}
Hope you had fun watching the video..!
""";
""".formatted(videoUrl);

ExternalSourcesPage.beginAt(this).ensureHost(Directive.Frame, videoHost);

goToProjectHome();
log("Creating the wiki with video");
Expand All @@ -177,7 +183,7 @@ public void testEmbeddedVideoInWiki()
wikiHelper.setWikiBody(wikiContent);
wikiHelper.saveWikiPage();

Assert.assertEquals("Video is missing", "https://www.youtube.com/embed/JEE4807UHN4",
Assert.assertEquals("Video is missing", videoUrl,
getAttribute(Locator.tag("iframe"), "src"));
}

Expand Down