Skip to content

Commit

Permalink
[#283] Updated ElementTrait.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexSkrypnyk committed Nov 2, 2024
1 parent 54c2ad6 commit 0f142fb
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 122 deletions.
5 changes: 5 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ A migration map of the step definitions available in v2 to v3.
| `When I edit :bundle :entity_type with title :label` | `When I edit eck :bundle :entity_type entity with the title :title` |
| `When I visit :bundle :entity_type with title :label` | `When I visit eck :bundle :entity_type entity with the title :title` |
|   | |
| **[`ElementTrait`](src/ElementTrait.php) ([example](tests/behat/features/element.feature))** | |
| `Then I( should) see the :selector element with the :attribute attribute set to :value` | `Then the element :selector with the attribute :attribute and the value :value should exist` |
| `I( should) see the :selector element with a(n) :attribute attribute containing :value` | `Then the element :selector with the attribute :attribute and the value containing :value should exist` |
| `Then I should see an element :selector using :type contains :text text` | Removed. Use `Then /^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]\|\\")*)"$/` instead. |
| &nbsp; | |
| **[`KeyboardTrait`](src/KeyboardTrait.php) ([example](tests/behat/features/keyboard.feature))** | |
| `Given I press the :keys keys` | `When I press the keys :keys` |
| `Given I press the :keys keys on :selector` | `When I press the keys :keys on the element :selector` |
Expand Down
4 changes: 3 additions & 1 deletion phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<description>Custom PHPCS standard.</description>

<!-- Coding standard. -->
<rule ref="Drupal"/>
<rule ref="Drupal">
<exclude name="Drupal.Files.LineLength.TooLong"/>
</rule>
<rule ref="Generic.PHP.RequireStrictTypes" />
<rule ref="PHPCompatibility"/>

Expand Down
6 changes: 5 additions & 1 deletion phpmd.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">

<rule ref="rulesets/unusedcode.xml"/>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="15"/>
</properties>
</rule>
<rule ref="rulesets/cleancode.xml/MissingImport">
<properties>
<property name="ignore-global" value="true"/>
Expand Down
137 changes: 64 additions & 73 deletions src/ElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace DrevOps\BehatSteps;

use Behat\Mink\Exception\ElementNotFoundException;

/**
* Trait Element.
*
Expand All @@ -16,106 +14,99 @@
trait ElementTrait {

/**
* Assert that an element with selector and attribute with a value exists.
* Assert an element with selector and attribute with a value exists.
*
* @Then I( should) see the :selector element with the :attribute attribute set to :value
* @Then the element :selector with the attribute :attribute and the value :value should exist
*/
public function elementAssertAttributeHasValue(string $selector, string $attribute, mixed $value): void {
$page = $this->getSession()->getPage();
$elements = $page->findAll('css', $selector);
public function elementAssertAttributeWithValueExists(string $selector, string $attribute, mixed $value): void {
$this->elementAssertAttributeWithValue($selector, $attribute, $value, TRUE, FALSE);
}

if (empty($elements)) {
throw new \Exception(sprintf('The "%s" element was not found on the page.', $selector));
}
/**
* Assert an element with selector and attribute containing a value exists.
*
* @Then the element :selector with the attribute :attribute and the value containing :value should exist
*/
public function elementAssertAttributeContainingValueExists(string $selector, string $attribute, mixed $value): void {
$this->elementAssertAttributeWithValue($selector, $attribute, $value, FALSE, FALSE);
}

$attr_found = FALSE;
$attr_value_found = FALSE;
foreach ($elements as $element) {
$attr = $element->getAttribute($attribute);
if (!empty($attr)) {
$attr_found = TRUE;
if (str_contains((string) $attr, strval($value))) {
$attr_value_found = TRUE;
break;
}
}
}
/**
* Assert an element with selector and attribute with a value exists.
*
* @Then the element :selector with the attribute :attribute and the value :value should not exist
*/
public function elementAssertAttributeWithValueNotExists(string $selector, string $attribute, mixed $value): void {
$this->elementAssertAttributeWithValue($selector, $attribute, $value, TRUE, TRUE);
}

if (!$attr_value_found) {
if (!$attr_found) {
throw new \Exception(sprintf('The "%s" attribute was not found on the element "%s".', $attribute, $selector));
}
else {
throw new \Exception(sprintf('The "%s" attribute was found on the element "%s", but does not contain a value "%s".', $attribute, $selector, $value));
}
}
/**
* Assert an element with selector and attribute containing a value does not exist.
*
* @Then the element :selector with the attribute :attribute and the value containing :value should not exist
*/
public function elementAssertAttributeContainingValueNotExists(string $selector, string $attribute, mixed $value): void {
$this->elementAssertAttributeWithValue($selector, $attribute, $value, FALSE, TRUE);
}

/**
* Assert element with wildcard pattern exists.
* Assert an element with selector and attribute with a value.
*
* Assert an element with selector and attribute with a value exists,
* matching a wildcard pattern.
* @param string $selector
* The CSS selector.
* @param string $attribute
* The attribute name.
* @param mixed $value
* The value to assert.
* @param bool $is_exact
* Whether to assert the value exactly.
* @param bool $is_inverted
* Whether to assert the value is not present.
*
* @Then I( should) see the :selector element with a(n) :attribute attribute containing :value
* @throws \Exception
*/
public function elementAssertAttributeContains(string $selector, string $attribute, string $pattern): void {
protected function elementAssertAttributeWithValue(string $selector, string $attribute, mixed $value, $is_exact, $is_inverted): void {
$page = $this->getSession()->getPage();
$elements = $page->findAll('css', $selector);

if (empty($elements)) {
throw new \Exception(sprintf('The "%s" element was not found on the page.', $selector));
throw new \Exception(sprintf('The "%s" element does not exist.', $selector));
}

$attr_found = FALSE;
$attr_pattern_matched = FALSE;

$attr_value_found = FALSE;
foreach ($elements as $element) {
$attr = (string) $element->getAttribute($attribute);
if (!empty($attr)) {
$attr_value = (string) $element->getAttribute($attribute);
if (!empty($attr_value)) {
$attr_found = TRUE;
// Convert wildcard pattern to regex.
$regex_pattern = '/' . str_replace(['*', '?'], ['.*', '.'], preg_quote($pattern, '/')) . '/';
if (preg_match($regex_pattern, $attr)) {
$attr_pattern_matched = TRUE;
if ($is_exact) {
if ($attr_value === strval($value)) {
$attr_value_found = TRUE;
break;
}
}
elseif (str_contains($attr_value, strval($value))) {
$attr_value_found = TRUE;
break;
}
}
}

if (!$attr_found) {
throw new \Exception(sprintf('The "%s" attribute was not found on the element "%s".', $attribute, $selector));
}

if (!$attr_pattern_matched) {
throw new \Exception(sprintf('No element with "%s" attribute matching the pattern "%s" found.', $attribute, $pattern));
throw new \Exception(sprintf('The "%s" attribute does not exist on the element "%s".', $attribute, $selector));
}
}

/**
* Assert that an element with selector contains text.
*
* @Then I should see an element :selector using :type contains :text text
*/
public function iShouldSeeAnElementUsingType(string $selector, string $type, string $text): void {
if ($type === 'css') {
$element = $this->getSession()->getPage()->find('css', $selector);
}
elseif ($type === 'xpath') {
$element = $this->getSession()->getPage()->find('xpath', $selector);
if ($is_inverted && $attr_value_found) {
$message = $is_exact
? sprintf('The "%s" attribute exists on the element "%s" with a value "%s", but it should not.', $attribute, $selector, $value)
: sprintf('The "%s" attribute exists on the element "%s" with a value containing "%s", but it should not.', $attribute, $selector, $value);
throw new \Exception($message);
}
else {
throw new \Exception('Selector type must be "css" or "xpath".');
}

if (!$element) {
$exception = new ElementNotFoundException($this->getSession()->getDriver(), NULL, $type, $selector);

throw new \Exception($exception->getMessage());
}

if (!str_contains($element->getText(), $text)) {
throw new \Exception(sprintf('The text "%s" was not found in the element "%s" using %s.', $text, $selector, $type));
elseif (!$is_inverted && !$attr_value_found) {
$message = $is_exact
? sprintf('The "%s" attribute exists on the element "%s" with a value "%s", but it does not have a value "%s".', $attribute, $selector, $attr_value, $value)
: sprintf('The "%s" attribute exists on the element "%s" with a value "%s", but it does not contain a value "%s".', $attribute, $selector, $attr_value, $value);
throw new \Exception($message);
}
}

Expand Down
12 changes: 6 additions & 6 deletions tests/behat/features/draggableviews.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ Feature: Check that DraggableViewsTrait works

When I visit "/draggableviews-demo"
And I save screenshot
Then I should see an element ".view-draggableviews-demo .views-row:first-child .views-field-title" using "css" contains "Test 2" text
And I should see an element ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" using "css" contains "Test 1" text
Then the ".view-draggableviews-demo .views-row:first-child .views-field-title" element should contain "Test 2"
And the ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" element should contain "Test 1"

When I save the draggable views items of the view "draggableviews_demo" and the display "draggableviews_demo_order" for the "draggableviews_demo" content in the following order:
| Test 1 |
| Test 2 |
And the cache has been cleared
And I visit "/draggableviews-demo"
Then I should see an element ".view-draggableviews-demo .views-row:first-child .views-field-title" using "css" contains "Test 1" text
And I should see an element ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" using "css" contains "Test 2" text
Then the ".view-draggableviews-demo .views-row:first-child .views-field-title" element should contain "Test 1"
And the ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" element should contain "Test 2"

When I save the draggable views items of the view "draggableviews_demo" and the display "draggableviews_demo_order" for the "draggableviews_demo" content in the following order:
| Test 2 |
| Test 1 |
And the cache has been cleared
And I visit "/draggableviews-demo"
Then I should see an element ".view-draggableviews-demo .views-row:first-child .views-field-title" using "css" contains "Test 2" text
And I should see an element ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" using "css" contains "Test 1" text
Then the ".view-draggableviews-demo .views-row:first-child .views-field-title" element should contain "Test 2"
And the ".view-draggableviews-demo .views-row:nth-child(2) .views-field-title" element should contain "Test 1"

@trait:DraggableViewsTrait
Scenario: Assert that negative assertion for "When I save the draggable views items of the view :view_id and the display :views_display_id for the :bundle content in the following order:" step throws an exception
Expand Down
Loading

0 comments on commit 0f142fb

Please sign in to comment.