Skip to content

[java][js] Fixed bug #13642 related to relative locators #14336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: trunk
Choose a base branch
from
Open
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
49 changes: 48 additions & 1 deletion common/src/web/relative_locators.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@
.big-rectangle {
border: 1px solid black;
width: 150px;
height: 400px;
height: 400px;
}
#bug-13642-table {
border-collapse: collapse;
margin-top: 25px;
margin-bottom: 25px;
}
th {
border: solid;
}
</style>
</head>
Expand All @@ -29,6 +37,45 @@ <h1>Relative Locator Tests</h1>
<p id="mid">This is a paragraph of text in the middle.
<p id="below">This text is below.

<table id="bug-13642-table">
<tbody>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</tbody>
</table>

<table>
<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@

class RelativeLocatorTest extends JupiterTestBase {

@Test
void shouldBeAbleToFindElementWithToRightOfAndBelowWithBorderCollapseInTable() {
driver.get(appServer.whereIs("relative_locators.html"));

By contactNameForTargetCompany =
RelativeLocator.with(By.tagName("td"))
.toRightOf(By.xpath("//td[text()='Alfreds Futterkiste']"))
.below(By.xpath("//th[text()='Contact']"));

String actualName = driver.findElement(contactNameForTargetCompany).getText();

assertThat(actualName).isEqualTo("Maria Anders");
}

@Test
void shouldBeAbleToFindElementsAboveAnotherWithTagName() {
driver.get(appServer.whereIs("relative_locators.html"));
Expand Down
57 changes: 40 additions & 17 deletions javascript/atoms/locators/relative.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ goog.require('bot.locators');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.math.Rect');
goog.require('goog.style');


/**
Expand Down Expand Up @@ -79,23 +80,44 @@ bot.locators.relative.above_ = function (selector) {


/**
* Relative locator to find elements that are below the expected one. "Below"
* is defined as where the top of the element found by `selector` is below the
* bottom of an element we're comparing to.
*
* Relative locator to find elements that are below the expected one. An element is "below" either when:
* 1. The bottom of the element found by `selector` is above the top of an element we're comparing to
* 2. Or the bottom of the element found by `selector` is at the same vertical position as the element we're comparing
* to and the two elements are cells of the same table.
* @param {!Element|function():!Element|!Object} selector Mechanism to be used to find the element.
* @return {!Filter} A function that determines whether the selector is below the given element.
* @private
*/
bot.locators.relative.below_ = function (selector) {
return bot.locators.relative.proximity_(
selector,
function (rect1, rect2) {
var bottom = rect1.top + rect1.height;
return bottom < rect2.top;
});
var toReturn = function (compareTo) {
var element = bot.locators.relative.resolve_(selector);
var rect1 = bot.dom.getClientRect(element);
var rect2 = bot.dom.getClientRect(compareTo);
var bottom = rect1.top + rect1.height;
return (bottom < rect2.top) || ((bottom == rect2.top) && twoElementsAreCellsOfSameTable(element, compareTo));
};
return toReturn;
};

/**
* Verifies if element and compareTo are table cells (i.e. td or th elements) and if they are part of the same table.
* @param {*} element Base element of the comparison (for example, for the bot.locators.relative.rightOf_ method, it
* would be the element we want to find an element to the right of)
* @param {*} compareTo Current element
* @returns True only if element and compareTo are table cells (i.e. td or th elements) and if they are part of the same
* table.
*/
function twoElementsAreCellsOfSameTable(element, compareTo) {
var tableCellsTagNames = ["TD", "TH"];
var elementAndCompareToAreTableCellElements =
tableCellsTagNames.includes(element.tagName) &&
tableCellsTagNames.includes(compareTo.tagName);
var cssSelector = "table";
var elementTable = element.closest(cssSelector);
var compareToTable = compareTo.closest(cssSelector);
var elementAndCompareToAreFromSameTable = elementTable.isEqualNode(compareToTable);
return elementAndCompareToAreTableCellElements && elementAndCompareToAreFromSameTable;
}

/**
* Relative locator to find elements that are to the left of the expected one.
Expand All @@ -122,15 +144,16 @@ bot.locators.relative.leftOf_ = function (selector) {
* @private
*/
bot.locators.relative.rightOf_ = function (selector) {
return bot.locators.relative.proximity_(
selector,
function (rect1, rect2) {
var right = rect1.left + rect1.width;
return right < rect2.left;
});
var toReturn = function (compareTo) {
var element = bot.locators.relative.resolve_(selector);
var rect1 = bot.dom.getClientRect(element);
var rect2 = bot.dom.getClientRect(compareTo);
var right = rect1.left + rect1.width;
return (right < rect2.left) || ((right == rect2.left) && twoElementsAreCellsOfSameTable(element, compareTo));
};
return toReturn;
};


/**
* Find elements within (by default) 50 pixels of the selected element. An
* element is not near itself.
Expand Down
Loading