Skip to content

Commit

Permalink
[plugin-web-app] Add step to save size and coordinates of an element (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
uarlouski authored Jan 9, 2024
1 parent b1221a9 commit b9ed698
Show file tree
Hide file tree
Showing 14 changed files with 268 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docs/modules/plugins/pages/plugin-web-app-playwright.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,6 @@ When I change context to element located by `id(username)`
When I save text of context element to scneario variable `username`
----

include::plugins:partial$ui-size-and-coordinates-steps.adoc[]

include::plugins:partial$common-web-app-text-steps.adoc[]
2 changes: 2 additions & 0 deletions docs/modules/plugins/partials/dynamic-variables-ui.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
=== Context element rectangle

IMPORTANT: Context element rectangle dynamic variables are deprecated and will be removed in VIVIDUS 0.7.0, please use <<_save_size_and_coordinates_of_element>> step.

The set of dynamic variables provides ability to access context element
coordinates, width and height.

Expand Down
2 changes: 2 additions & 0 deletions docs/modules/plugins/partials/generic-ui-steps.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ When I save number of elements located by `tagName(a)` to scenario variable `num
Then `${numberOfLinks}` is equal to `1`
----

include::plugins:partial$ui-size-and-coordinates-steps.adoc[]

=== Element existence during the time period

Validates the element located by the locator has existed for the period
Expand Down
42 changes: 42 additions & 0 deletions docs/modules/plugins/partials/ui-size-and-coordinates-steps.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
=== Save size and coordinates of element

Saves the information about the size of an element and its coordinates relative to the viewport.

[source,gherkin]
----
When I save coordinates and size of element located by `$locator` to $scopes variable `$variableName`
----

* `$locator` - <<_locator>>.
* `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes].
* `$variableName` - The name of the variable to save the coordinates and size of an element which can be accessed on the variable name using dot notation (please see examples section):
+
[cols="1,3", options="header"]
|===
|Attribute
|Description

|`x`
|the `x` coordinate

|`y`
|the `y` coordinate

|`height`
|the `height` of the element

|`width`
|the `width` of the element

|===

.Verify image size and coordinates
[source,gherkin]
----
When I save coordinates and size of element located by `tagName(img)` to scenario variable `rect`
Then `${rect.height}` is equal `400`
Then `${rect.width}` is equal `400`
Then `${rect.x}` is equal `200`
Then `${rect.y}` is equal `8`
----
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package org.vividus.steps.ui;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -230,4 +231,60 @@ private void saveAttributeValueOfElement(Optional<WebElement> element, String at
return value;
}).ifPresent(value -> variableContext.putVariable(scopes, variableName, value));
}

/**
* Saves the information about the size of an element and its coordinates relative to the viewport.
*
* @param locator The locator to find an element
* @param scopes The set (comma separated list of scopes e.g.: STORY, NEXT_BATCHES) of variable's scope<br>
* <i>Available scopes:</i>
* <ul>
* <li><b>STEP</b> - the variable will be available only within the step,
* <li><b>SCENARIO</b> - the variable will be available only within the scenario,
* <li><b>STORY</b> - the variable will be available within the whole story,
* <li><b>NEXT_BATCHES</b> - the variable will be available starting from next batch
* </ul>
* @param variableName The name of the variable to save the coordinates and size of an element which can be
* accessed on the variable name using dot notation:
* <table>
* <caption>A table of size and coordinate properties</caption>
* <thead>
* <tr>
* <th><b>attribute</b></th>
* <th><b>description</b></th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>x</td>
* <td>the x coordinate</td>
* </tr>
* <tr>
* <td>y</td>
* <td>the y coordinate</td>
* </tr>
* <tr>
* <td>height</td>
* <td>the height of the element</td>
* </tr>
* <tr>
* <td>width</td>
* <td>the width of the element</td>
* </tr>
* </tbody>
* </table>
*/
@When("I save coordinates and size of element located by `$locator` to $scopes variable `$variableName`")
public void saveElementCoordinatesAndSize(Locator locator, Set<VariableScope> scopes, String variableName)
{
baseValidations.assertElementExists("The element to get size and coordinates", locator)
.map(WebElement::getRect)
.map(rect -> Map.of(
"x", rect.getX(),
"y", rect.getY(),
"height", rect.getHeight(),
"width", rect.getWidth())
)
.ifPresent(rect -> variableContext.putVariable(scopes, variableName, rect));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,24 +20,41 @@

import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vividus.ui.context.UiContext;
import org.vividus.variable.DynamicVariable;
import org.vividus.variable.DynamicVariableCalculationResult;

@Deprecated(forRemoval = true, since = "0.6.6")
public abstract class AbstractSearchContextRectangleDynamicVariable implements DynamicVariable
{
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSearchContextRectangleDynamicVariable.class);

private final String expression;
private final String attribute;
private final UiContext uiContext;
private final ToIntFunction<Rectangle> valueProvider;

protected AbstractSearchContextRectangleDynamicVariable(UiContext uiContext, ToIntFunction<Rectangle> valueProvider)
protected AbstractSearchContextRectangleDynamicVariable(String expression, String attribute, UiContext uiContext,
ToIntFunction<Rectangle> valueProvider)
{
this.expression = expression;
this.attribute = attribute;
this.uiContext = uiContext;
this.valueProvider = valueProvider;
}

@Override
public DynamicVariableCalculationResult calculateValue()
{
LOGGER.atWarn().addArgument(expression)
.addArgument("When I save coordinates and size of element located by `$locator` to $scopes "
+ "variable `$variableName`")
.addArgument(attribute)
.log("The '{}' dynamic variable is deprecated and will be removed in VIVIDUS 0.7.0, please use"
+ " '{}' step to save location adn coodinates, and then use '{}' property to get target "
+ "value.");
return DynamicVariableCalculationResult.withValueOrError(
uiContext.getSearchContext(WebElement.class)
.map(WebElement::getRect)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,10 +19,11 @@
import org.openqa.selenium.Rectangle;
import org.vividus.ui.context.UiContext;

@Deprecated(forRemoval = true, since = "0.6.6")
public class SearchContextHeightDynamicVariable extends AbstractSearchContextRectangleDynamicVariable
{
public SearchContextHeightDynamicVariable(UiContext uiContext)
{
super(uiContext, Rectangle::getHeight);
super("context-height", "height", uiContext, Rectangle::getHeight);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,10 +19,11 @@
import org.openqa.selenium.Rectangle;
import org.vividus.ui.context.UiContext;

@Deprecated(forRemoval = true, since = "0.6.6")
public class SearchContextWidthDynamicVariable extends AbstractSearchContextRectangleDynamicVariable
{
public SearchContextWidthDynamicVariable(UiContext uiContext)
{
super(uiContext, Rectangle::getWidth);
super("context-width", "width", uiContext, Rectangle::getWidth);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,10 +19,11 @@
import org.openqa.selenium.Rectangle;
import org.vividus.ui.context.UiContext;

@Deprecated(forRemoval = true, since = "0.6.6")
public class SearchContextXCoordinateDynamicVariable extends AbstractSearchContextRectangleDynamicVariable
{
public SearchContextXCoordinateDynamicVariable(UiContext uiContext)
{
super(uiContext, Rectangle::getX);
super("context-x-coordinate", "x", uiContext, Rectangle::getX);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,10 +19,11 @@
import org.openqa.selenium.Rectangle;
import org.vividus.ui.context.UiContext;

@Deprecated(forRemoval = true, since = "0.6.6")
public class SearchContextYCoordinateDynamicVariable extends AbstractSearchContextRectangleDynamicVariable
{
public SearchContextYCoordinateDynamicVariable(UiContext uiContext)
{
super(uiContext, Rectangle::getY);
super("context-y-coordinate", "y", uiContext, Rectangle::getY);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,7 @@
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand All @@ -35,6 +36,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.vividus.context.VariableContext;
import org.vividus.selenium.locator.Locator;
Expand Down Expand Up @@ -171,4 +173,23 @@ void shouldNotSaveAttributeValueOfElementIfTheValueIsNotFound()
verify(softAssert).recordFailedAssertion(String.format("The '%s' attribute does not exist", ATTRIBUTE_NAME));
verifyNoInteractions(variableContext);
}

@Test
void shouldSaveElementCoordinatesAndSize()
{
Locator locator = mock(Locator.class);
WebElement webElement = mock(WebElement.class);
when(baseValidations.assertElementExists("The element to get size and coordinates", locator))
.thenReturn(Optional.of(webElement));
Rectangle rectangle = new Rectangle(1, 2, 3, 4);
when(webElement.getRect()).thenReturn(rectangle);

genericSetVariableSteps.saveElementCoordinatesAndSize(locator, VARIABLE_SCOPE, VARIABLE_NAME);

verify(variableContext).putVariable(VARIABLE_SCOPE, VARIABLE_NAME, Map.of(
"x", rectangle.getX(),
"y", rectangle.getY(),
"height", rectangle.getHeight(),
"width", rectangle.getWidth()));
}
}
Loading

0 comments on commit b9ed698

Please sign in to comment.