Skip to content

Commit

Permalink
[plugin-web-app-playwright] Add element wait steps (#5224)
Browse files Browse the repository at this point in the history
  • Loading branch information
avinBar authored Jul 18, 2024
1 parent e9e4c96 commit 3d313ab
Show file tree
Hide file tree
Showing 10 changed files with 425 additions and 121 deletions.
34 changes: 9 additions & 25 deletions docs/modules/plugins/pages/plugin-web-app-playwright.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -250,41 +250,25 @@ include::plugins:partial$ui-size-and-coordinates-steps.adoc[]

include::plugins:partial$common-web-app-text-steps.adoc[]

=== Wait for element appearance
include::plugins:partial$ui-wait-element-state-steps.adoc[]

Waits for appearance of the element by the locator.
=== Wait for element state

[source,gherkin]
----
When I wait until element located by `$locator` appears
----

* `$locator` - <<_locator>>.

.Wait for appearance of the element with the specified id
[source,gherkin]
----
When I wait until element located by `id(welcome-image)` appears
----


=== Wait for element disappearance

Waits for disappearance of the element by the locator.

NOTE: If the element doesn't exist on the page/context, the step will immediately complete successfully.
Waits for an element, located by the specified locator in the given search context, to change to the specified state.

[source,gherkin]
----
When I wait until element located by `$locator` disappears
When I wait until state of element located by `$locator` is $state
----

* `$locator` - <<_locator>>.
* `$locator` - The <<_locator,locator>> used to find element.
* `$state` - The expected element xref:parameters:state.adoc[state].

.Wait for disappearance of the element with the specified id
.Click on the button and wait until the element becomes invisible
[source,gherkin]
----
When I wait until element located by `id(welcome-image)` disappears
When I click on element located by `id(signInButton)`
When I wait until state of element located by `id(signInButton):a` is NOT VISIBLE
----

=== Wait for expected elements number
Expand Down
64 changes: 1 addition & 63 deletions docs/modules/plugins/partials/generic-ui-steps.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,69 +36,7 @@ When I take screenshot and save it to folder `$screenshotFilePath`
When I take screenshot and save it to file at path `${screenshot-directory}/start-page.png`
----

=== Wait for element appearance

Waits for appearance of the element by the locator.

WARNING: It's forbidden to use <<_visibility_types>> in the locator.

[source,gherkin]
----
When I wait until element located by `$locator` appears
----

* `$locator` - <<_locator>>.

.Wait for appearance of the element with the specified name
[source,gherkin]
----
When I wait until element located by `name(welcome-image)` appears
----


=== Wait for element disappearance

Waits for disappearance of the element by the locator.

NOTE: If the element doesn't exist on the page/context, the step will immediately complete successfully.
Checking the element on the page (if needed) should be done in a separate step (e.g. <<_wait_for_element_appearance>> or xref:plugin-html.adoc#_validate_elements[Validate elements]).

WARNING: It's forbidden to use <<_visibility_types>> in the locator.

[source,gherkin]
----
When I wait until element located by `$locator` disappears
----

* `$locator` - <<_locator>>.

.Wait for disappearance of the element with the specified name
[source,gherkin]
----
When I wait until element located by `name(welcome-image)` disappears
----


=== Wait for element with specified state using polling interval

Waits for an element with the specified state to be found using the specified timeout with polling interval.

[source,gherkin]
----
When I wait `$duration` with `$pollingDuration` polling until element located by `$locator` becomes $state
----

* `$duration` - Total duration to wait in the {iso-date-format-link} format.
* `$pollingDuration` - The duration to wait between search retries in the {iso-date-format-link} format.
* `$locator` - The <<_locator,locator>> of the element to wait for state change.
* `$state` - The element xref:parameters:state.adoc[state].

.Verify that the element become invisible up to 10 times
[source,gherkin]
----
When I wait `PT10S` with `PT1S` polling until element located by `id(element-to-hide)` becomes not visible
----

include::plugins:partial$ui-wait-element-state-steps.adoc[]

=== Wait for expected elements number

Expand Down
60 changes: 60 additions & 0 deletions docs/modules/plugins/partials/ui-wait-element-state-steps.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
=== Wait for element appearance

Waits for appearance of the element by the locator.

WARNING: It's forbidden to use <<_visibility_types>> in the locator.

[source,gherkin]
----
When I wait until element located by `$locator` appears
----

* `$locator` - <<_locator>>.
.Wait for appearance of the element with the specified name
[source,gherkin]
----
When I wait until element located by `id(welcome-image)` appears
----

=== Wait for element disappearance

Waits for disappearance of the element by the locator.

NOTE: If the element doesn't exist on the page/context, the step will immediately complete successfully.
Checking the element on the page (if needed) should be done in a separate step (e.g. <<_wait_for_element_appearance>> or xref:plugin-html.adoc#_validate_elements[Validate elements]).

WARNING: It's forbidden to use <<_visibility_types>> in the locator.

[source,gherkin]
----
When I wait until element located by `$locator` disappears
----

* `$locator` - <<_locator>>.

.Wait for disappearance of the element with the specified name
[source,gherkin]
----
When I wait until element located by `id(welcome-image)` disappears
----

=== Wait for element with specified state using polling interval

Waits for an element with the specified state to be found using the specified timeout with polling interval.

[source,gherkin]
----
When I wait `$duration` with `$pollingDuration` polling until element located by `$locator` becomes $state
----

* `$duration` - Total duration to wait in the {iso-date-format-link} format.
* `$pollingDuration` - The duration to wait between search retries in the {iso-date-format-link} format.
* `$locator` - The <<_locator,locator>> of the element to wait for state change.
* `$state` - The element xref:parameters:state.adoc[state].

.Verify that the element become invisible up to 10 times
[source,gherkin]
----
When I wait `PT10S` with `PT1S` polling until element located by `id(element-to-hide)` becomes not visible
----
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,20 @@
import com.microsoft.playwright.TimeoutError;

import org.vividus.softassert.ISoftAssert;
import org.vividus.ui.web.playwright.assertions.PlaywrightSoftAssert;

public class WaitActions
{
private static final String PASSED_CONDITION = "Passed wait condition: ";
private static final String FAILED_CONDITION = "Failed wait condition: ";

private final ISoftAssert softAssert;
private final PlaywrightSoftAssert playwrightSoftAssert;

public WaitActions(ISoftAssert softAssert)
public WaitActions(ISoftAssert softAssert, PlaywrightSoftAssert playwrightSoftAssert)
{
this.softAssert = softAssert;
this.playwrightSoftAssert = playwrightSoftAssert;
}

public void runWithTimeoutAssertion(String conditionDescription, Runnable timeoutOperation)
Expand All @@ -41,12 +47,19 @@ public void runWithTimeoutAssertion(Supplier<String> conditionDescription, Runna
try
{
timeoutOperation.run();
softAssert.recordPassedAssertion("Passed wait condition: " + conditionDescription.get());
softAssert.recordPassedAssertion(PASSED_CONDITION + conditionDescription.get());
}
catch (TimeoutError e)
{
softAssert.recordFailedAssertion(
"Failed wait condition: " + conditionDescription.get() + ". " + e.getMessage(), e);
softAssert.recordFailedAssertion(FAILED_CONDITION + conditionDescription.get() + ". " + e.getMessage(), e);
}
}

public void runTimeoutPlaywrightAssertion(Supplier<String> conditionDescription, Runnable timeoutAssertOperation)
{
playwrightSoftAssert.runAssertion(() -> FAILED_CONDITION + conditionDescription.get(), () -> {
timeoutAssertOperation.run();
softAssert.recordPassedAssertion(PASSED_CONDITION + conditionDescription.get());
});
}
}
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 @@ -16,6 +16,8 @@

package org.vividus.ui.web.playwright.assertions;

import java.util.function.Supplier;

import org.opentest4j.AssertionFailedError;
import org.vividus.softassert.ISoftAssert;

Expand All @@ -29,14 +31,19 @@ public PlaywrightSoftAssert(ISoftAssert softAssert)
}

public void runAssertion(String messageOnFailure, Runnable assertion)
{
runAssertion(() -> messageOnFailure, assertion);
}

public void runAssertion(Supplier<String> messageOnFailure, Runnable assertion)
{
try
{
assertion.run();
}
catch (AssertionFailedError e)
{
softAssert.recordFailedAssertion(messageOnFailure + ". " + e.getMessage(), e);
softAssert.recordFailedAssertion(messageOnFailure.get() + ". " + e.getMessage(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementEnabled(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementEnabled(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return locator.isEnabled(new Locator.IsEnabledOptions().setTimeout(NO_WAIT_TIMEOUT));
}
},
DISABLED
{
Expand All @@ -37,6 +49,18 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementDisabled(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementDisabled(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return locator.isDisabled(new Locator.IsDisabledOptions().setTimeout(NO_WAIT_TIMEOUT));
}
},
SELECTED
{
Expand All @@ -45,6 +69,18 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementSelected(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementSelected(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return isElementSelected(locator);
}
},
NOT_SELECTED
{
Expand All @@ -53,6 +89,18 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementNotSelected(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementNotSelected(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return !isElementSelected(locator);
}
},
VISIBLE
{
Expand All @@ -61,6 +109,18 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementVisible(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementVisible(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return locator.isVisible();
}
},
NOT_VISIBLE
{
Expand All @@ -69,7 +129,30 @@ public void assertElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementHidden(locator, false);
}

@Override
public void waitForElementState(Locator locator)
{
PlaywrightLocatorAssertions.assertElementHidden(locator, true);
}

@Override
public boolean isElementState(Locator locator)
{
return locator.isHidden();
}
};

private static final int NO_WAIT_TIMEOUT = 0;

public abstract void assertElementState(Locator locator);

public abstract void waitForElementState(Locator locator);

public abstract boolean isElementState(Locator locator);

private static boolean isElementSelected(Locator locator)
{
return locator.isChecked(new Locator.IsCheckedOptions().setTimeout(NO_WAIT_TIMEOUT));
}
}
Loading

0 comments on commit 3d313ab

Please sign in to comment.