|
| 1 | +=== Relative Locators |
| 2 | + |
| 3 | +Relative locators enable finding elements based on their relationship to other elements on the page. |
| 4 | +This simplifies working with dynamic layouts by allowing flexible and context-aware element identification. |
| 5 | + |
| 6 | +==== Relative locator format |
| 7 | +---- |
| 8 | +By.relative([rootElementLocator]>>relativePosition([relativeElementLocator])):[visibility]->filter.[filterType]([filterValue]) |
| 9 | +---- |
| 10 | + |
| 11 | +[IMPORTANT] |
| 12 | +By. prefix is optional. |
| 13 | + |
| 14 | +[WARNING] |
| 15 | +==== |
| 16 | +Root element locator type can be only: id, cssSelector, xPath, unnormalizedXPath, tagName, className, caseInsensitiveText, imageSrc, imageSrcPart, fieldName, radioButton, shadowCssSelector |
| 17 | +==== |
| 18 | + |
| 19 | +. `rootElementLocator` - *[mandatory]* common VIVIDUS locator for elements to find |
| 20 | +. `relativePosition` - *[mandatory]* how root elements placed against relative element. See the table below |
| 21 | +. `relativeElementLocator` - *[mandatory]* common VIVIDUS locator for elements to find. Supports all VIVIDUS locator types. |
| 22 | +. `visibility` - *[optional]* visibility of root elements (visible by default) |
| 23 | +. `filterType` - *[optional]* type of the filter for root elements |
| 24 | +. `filterValue` - *[required if filter type defined]* value of the filter |
| 25 | + |
| 26 | +.Locate elements by xpath = '//div' placed below relative element with id = 'title' |
| 27 | +---- |
| 28 | +relative(xpath(//div)>>below(id(title))) |
| 29 | +---- |
| 30 | + |
| 31 | +You can also chain locators if needed. Sometimes the element is most easily identified as being both above/below one element and right/left of another. |
| 32 | + |
| 33 | +.Chaining relative locators |
| 34 | +---- |
| 35 | +relative(xpath(//div)>>below(className(header))>>toRightOf(id(left_menu))>>above(xpath(//div[@testId='footer']))) |
| 36 | +---- |
| 37 | + |
| 38 | +[cols="2,3,3", options="header", title="Supported relative positions"] |
| 39 | +|=== |
| 40 | + |
| 41 | +|Relative position |
| 42 | +|Example |
| 43 | +|Description |
| 44 | + |
| 45 | +|`above` |
| 46 | +|relative(xpath(//div)>>above(id(bottom_block))) |
| 47 | +|Locates elements matching xpath `//div` and placed *above* of relative element with id = bottom_block |
| 48 | + |
| 49 | +|`below` |
| 50 | +|relative(xpath(//div)>>below(id(top_block))) |
| 51 | +|Locates elements matching xpath `//div` and placed *below* of relative element with id = top_block |
| 52 | + |
| 53 | +|`toLeftOf` |
| 54 | +|relative(xpath(//div)>>toLeftOf(id(right_block))) |
| 55 | +|Locates elements matching xpath `//div` and placed *to the left of* relative element with id = right_block |
| 56 | + |
| 57 | +|`toRightOf` |
| 58 | +|relative(xpath(//div)>>toRightOf(id(left_block))) |
| 59 | +|Locates elements matching xpath `//div` and placed *to the right of* relative element with id = left_block |
| 60 | + |
| 61 | +|`near` |
| 62 | +|relative(xpath(//div)>>near(id(near_block))) |
| 63 | +|Locates elements matching xpath `//div` and placed at most *50px* away (in any direction) from the relative element with id = near_block |
| 64 | + |
| 65 | +|`nearXpx` |
| 66 | +|relative(xpath(//div)>>near200px(id(distant_block))) |
| 67 | +|Provide possibility to configure max distance between near elements. |
| 68 | + |
| 69 | +Locates elements matching xpath `//div` and placed at most *200px* away (in any direction) from the relative element with id = distant_block |
| 70 | + |
| 71 | +|=== |
| 72 | + |
| 73 | +==== Examples |
| 74 | + |
| 75 | +.Verify a number of elements with xpath = `//div` placed relative to other elements |
| 76 | +[source,gherkin] |
| 77 | +---- |
| 78 | +Then number of elements found by `relative(xpath(//div)>>below(id(title)))` is = `1` |
| 79 | +Then number of elements found by `relative(xpath(//div)>>toLeftOf(id(right_image)))` is = `3` |
| 80 | +---- |
| 81 | + |
| 82 | +.Verify that two elements aren't placed in the specific relative position |
| 83 | +[source,gherkin] |
| 84 | +---- |
| 85 | +Then number of elements found by `id(block1)` is = `1` |
| 86 | +Then number of elements found by `id(block2)` is = `1` |
| 87 | +Then number of elements found by `relative(id(block1)>>toRightOf(id(block2)))` is = `0` |
| 88 | +---- |
| 89 | + |
| 90 | +.Different locator types in the relative locators |
| 91 | +[source,gherkin] |
| 92 | +---- |
| 93 | +Then number of elements found by `relative(id(block1)>>toLeftOf(className(item2)))` is = `1` |
| 94 | +Then number of elements found by `relative(className(item1)>>toLeftOf(cssSelector(.item2)))` is = `1` |
| 95 | +Then number of elements found by `relative(xpath(//div[@id='block1'])>>toLeftOf(name(item2)))` is = `1` |
| 96 | +---- |
| 97 | + |
| 98 | +.Verify number of invisible elements with xpath = '//div' and placed at the right of element with id = 'left-menu' |
| 99 | +[source,gherkin] |
| 100 | +---- |
| 101 | +Then number of elements found by `relative(xpath(//div)>>toRightOf(id(left-menu))):i` is = `1` |
| 102 | +---- |
| 103 | + |
| 104 | +.Verify number of elements with xpath = '//div' and text part = 'some text' placed at the right of element with id = 'left-menu' |
| 105 | +[source,gherkin] |
| 106 | +---- |
| 107 | +Then number of elements found by `relative(xpath(//div)>>toRightOf(id(left-menu)))->filter.textPart(some text)` is = `1``1` |
| 108 | +---- |
| 109 | + |
| 110 | +.Apply filter to the inner relative element locator |
| 111 | +[source,gherkin] |
| 112 | +---- |
| 113 | +Then number of elements found by `relative(xpath(//div)>>above(xpath(//a)->filter.linkUrlPart(links)))` is = `1` |
| 114 | +---- |
0 commit comments