GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 8.x-2.x ( 49ff7d...6e155c )
by Devin
06:16
created

UtilityContext::iWriteTextIntoField()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Acquia\DFExtension\Context;
4
5
use Behat\Mink\Driver\Selenium2Driver;
6
use Behat\Mink\Element\ElementInterface;
7
use Behat\Mink\Exception\ExpectationException;
8
use Drupal\Component\Utility\Random;
9
use Drupal\DrupalExtension\Context\DrupalSubContextBase;
10
use WebDriver\Exception\NoAlertOpenError;
11
12
/**
13
 * A context with miscellaneous helpers.
14
 */
15
class UtilityContext extends DrupalSubContextBase {
16
17
  /**
18
   * Asserts that a form field is not present.
19
   *
20
   * @param string $field
21
   *   The field locator.
22
   *
23
   * @Then I should not see a :field field
24
   */
25
  public function assertFieldNotExists($field) {
26
    $this->assertSession()->fieldNotExists($field);
27
  }
28
29
  /**
30
   * Asserts that a certain number of elements match a CSS selector.
31
   *
32
   * @param string $selector
33
   *   The selector.
34
   * @param int $count
35
   *   The number of elements expected to match the selector.
36
   *
37
   * @throws ExpectationException
38
   *   If the number of elements that match the selector is not the expected
39
   *   number.
40
   *
41
   * @Then :count element(s) should match :selector
42
   */
43 View Code Duplication
  public function assertSelectorMatch($selector, $count) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
44
    $session = $this->getSession();
45
46
    $result = count($session->getPage()->findAll('css', $selector));
47
48
    if ($result != $count) {
49
      throw new ExpectationException(
50
        '"' . $selector . '" matched ' . $result . ' element(s), expected ' . $count . '.',
51
        $session->getDriver()
52
      );
53
    }
54
  }
55
56
  /**
57
   * Asserts that a minimum number of elements match a CSS selector.
58
   *
59
   * @param string $selector
60
   *   The selector.
61
   * @param int $count
62
   *   The number of elements expected to match the selector.
63
   *
64
   * @throws ExpectationException
65
   *   If the number of elements that match the selector is less than expected.
66
   *
67
   * @Then at least :count element(s) should match :selector
68
   */
69 View Code Duplication
  public function assertSelectorMatchAtLeast($selector, $count) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
    $session = $this->getSession();
71
72
    $result = count($session->getPage()->findAll('css', $selector));
73
74
    if ($result < $count) {
75
      throw new ExpectationException(
76
        '"' . $selector . '" matched ' . $result . ' element(s), expected at least ' . $count . '.',
77
        $session->getDriver()
78
      );
79
    }
80
  }
81
82
  /**
83
   * Asserts that no elements match a CSS selector.
84
   *
85
   * @param string $selector
86
   *   The selector.
87
   *
88
   * @Then no elements should match :selector
89
   * @Then nothing should match :selector
90
   */
91
  public function assertSelectorMatchNothing($selector) {
92
    $this->assertSelectorMatch($selector, 0);
93
  }
94
95
  /**
96
   * Asserts than an element is empty.
97
   *
98
   * @param string $selector
99
   *   The element's CSS selector.
100
   *
101
   * @throws ExpectationException
102
   *   If the element has any HTML content.
103
   *
104
   * @Then the :selector element(s) should be empty
105
   */
106
  public function assertElementIsEmpty($selector) {
107
    $content = $this->assertSession()->elementExists('css', $selector)->getHtml();
108
109
    if (trim($content)) {
110
      throw new ExpectationException(
111
        'Expected ' . $selector . ' to be empty but it is not.',
112
        $this->getSession()->getDriver()
113
      );
114
    }
115
  }
116
117
  /**
118
   * Clears a field.
119
   *
120
   * @param string $field
121
   *   The field to clear.
122
   * @param ElementInterface $container
123
   *   (optional) The containing element.
124
   *
125
   * @When I clear :field
126
   */
127
  public function clearField($field, ElementInterface $container = NULL) {
128
    $this->assertSession()->fieldExists($field, $container)->setValue(FALSE);
0 ignored issues
show
Bug introduced by
It seems like $container defined by parameter $container on line 127 can also be of type object<Behat\Mink\Element\ElementInterface>; however, Behat\Mink\WebAssert::fieldExists() does only seem to accept null|object<Behat\Mink\E...ent\TraversableElement>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
129
  }
130
131
  /**
132
   * Finds a collapsible details element by its summary text.
133
   *
134
   * @param string $summary_text
135
   *   The summary text.
136
   *
137
   * @return \Behat\Mink\Element\NodeElement|null
138
   *   The details element, or NULL if it was not found.
139
   */
140
  public function findCollapsible($summary_text) {
141
    /** @var \Behat\Mink\Element\NodeElement[] $elements */
142
    $elements = $this
143
      ->getSession()
144
      ->getPage()
145
      ->findAll('css', 'details > summary');
146
147
    foreach ($elements as $element) {
148
      if ($element->getText() == $summary_text) {
149
        return $element->getParent();
150
      }
151
    }
152
  }
153
154
  /**
155
   * Generates random image media assets.
156
   *
157
   * @param int $count
158
   *   (optional) How many to generate. Defaults to 1.
159
   *
160
   * @Given a random image
161
   * @Given :count random images
162
   */
163
  public function generateRandomImages($count = 1) {
164
    $random = new Random();
165
    $entity_type_manager = \Drupal::entityTypeManager();
166
167
    for ($i = 0; $i < $count; $i++) {
168
      $uri = $random->image(uniqid('public://random_') . '.png', '240x240', '640x480');
169
170
      /** @var \Drupal\file\FileInterface $file */
171
      $file = $entity_type_manager->getStorage('file')->create(['uri' => $uri]);
172
      $file->setMimeType('image/png');
173
      $file->setTemporary();
174
      $file->save();
175
176
      $media = $entity_type_manager->getStorage('media')->create([
177
        'bundle' => 'image',
178
        'name' => $random->name(32),
179
        'status' => TRUE,
180
        'image' => $file->id(),
181
        'field_media_in_library' => TRUE,
182
      ]);
183
      $media->save();
184
    }
185
  }
186
187
  /**
188
   * Accepts any currently open alert box(es), then optionally runs a callback.
189
   *
190
   * @param callable $then
191
   *   (optional) A function to run after accepting the alerts.
192
   * @param mixed[] $arguments
193
   *   (optional) Arguments for the callback.
194
   *
195
   * @When I accept the alert(s)
196
   */
197
  public function acceptAlerts(callable $then = NULL, array $arguments = []) {
198
    $driver = $this->getSession()->getDriver();
199
    if ($driver instanceof Selenium2Driver) {
200
      while (true) {
201
        try {
202
          $driver->getWebDriverSession()->accept_alert();
203
        }
204
        catch (NoAlertOpenError $e) {
205
          break;
206
        }
207
      }
208
    }
209
    if ($then) {
210
      call_user_func_array($then, $arguments);
211
    }
212
  }
213
214
  /**
215
   * "Manually" writes text into a field.
216
   *
217
   * @param string $text
218
   *   The text to write into the field.
219
   * @param string $field
220
   *   The label, placeholder, ID or name of the field.
221
   *
222
   * @Given I write :text into :field
223
   */
224
  public function iWriteTextIntoField($text, $field) {
225
    $this->getSession()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Mink\Driver\DriverInterface as the method getWebDriverSession() does only exist in the following implementations of said interface: Behat\Mink\Driver\Selenium2Driver.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
226
      ->getDriver()
227
      ->getWebDriverSession()
228
      ->element('xpath', $this->getSession()->getSelectorsHandler()->selectorToXpath('named_exact', array('field', $field)))
229
      ->postValue(['value' => [$text]]);
230
  }
231
232
}
233