GridWebContext::assertColumnCells()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 4
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Lug package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Lug\Bundle\GridBundle\Behat\Context;
13
14
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
15
use Behat\Mink\Driver\Selenium2Driver;
16
use Behat\Mink\Element\NodeElement;
17
use Behat\MinkExtension\Context\MinkAwareContext;
18
use Lug\Component\Behat\Context\AjaxContext;
19
use Lug\Component\Behat\Dictionary\MinkDictionary;
20
21
/**
22
 * @author GeLo <[email protected]>
23
 */
24
class GridWebContext implements MinkAwareContext
25
{
26
    use MinkDictionary;
27
28
    /**
29
     * @var AjaxContext
30
     */
31
    private $ajaxContext;
32
33
    /**
34
     * @BeforeScenario
35
     */
36
    public function init(BeforeScenarioScope $scope)
37
    {
38
        $environment = $scope->getEnvironment();
39
40
        $this->ajaxContext = $environment->getContext(AjaxContext::class);
41
    }
42
43
    public function toggleBatch()
44
    {
45
        $batch = $this->findBatch();
46
47
        $batch->isChecked() ? $batch->check() : $batch->uncheck();
48
    }
49
50
    /**
51
     * @param string|null $cell
52
     */
53
    public function selectBatch($cell = null)
54
    {
55
        $this->findBatch($cell)->check();
56
    }
57
58
    public function selectBatchAll()
59
    {
60
        $xpath = '//input[@id="grid_batch_all"]';
61
62
        \PHPUnit_Framework_Assert::assertNotNull(
63
            $node = $this->findGrid()->find('xpath', $xpath),
64
            'The grid "all" batch could not be found.'
65
        );
66
67
        $node->check();
68
    }
69
70
    /**
71
     * @param string|int $header
72
     * @param string     $sorting
73
     */
74
    public function followSortingLink($header, $sorting)
75
    {
76
        $xpath = '//a[@title="'.($sorting === 'ASC' ? 'Ascending' : 'Descending').'"]';
77
78
        \PHPUnit_Framework_Assert::assertNotNull(
79
            $node = $this->findHeader($header)->find('xpath', $xpath),
80
            sprintf('The grid column sorting link "%s" (%s) could not be found.', $header, $sorting)
81
        );
82
83
        $node->click();
84
    }
85
86
    /**
87
     * @param string $cell
88
     * @param string $link
89
     */
90
    public function followColumnActionLink($cell, $link)
91
    {
92
        $xpath = '/../td[last()]//*[text()[contains(., "'.$link.'")]]';
93
94
        \PHPUnit_Framework_Assert::assertNotNull(
95
            $node = $this->findCell(null, null, $cell)->find('xpath', $xpath),
96
            sprintf('The column action link "%s" of the cell "%s" could not be found.', $link, $cell)
97
        );
98
99
        $node->click();
100
    }
101
102
    public function waitFilters()
103
    {
104
        if ($this->getDriver() instanceof Selenium2Driver) {
105
            $this->getSession()->wait('10000', '$(\'#grid_modal h4\').is(\':visible\')');
106
        }
107
    }
108
109
    public function waitFiltersRefresh()
110
    {
111
        $this->ajaxContext->waitAjax();
112
    }
113
114
    /**
115
     * @param mixed[] $rows
116
     */
117
    public function assertGrid(array $rows)
118
    {
119
        $this->assertHeaders($rows[0]);
120
        $this->assertBody(array_slice($rows, 1));
121
    }
122
123
    /**
124
     * @param string[] $columns
125
     */
126 View Code Duplication
    public function assertHeaders(array $columns)
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...
127
    {
128
        $offset = $this->hastBatch() ? 2 : 1;
129
130
        foreach ($columns as $column => $value) {
131
            $this->assertHeader($column + $offset, $value);
132
        }
133
    }
134
135
    /**
136
     * @param string|int $header
137
     * @param string     $value
138
     */
139
    public function assertHeader($header, $value)
140
    {
141
        \PHPUnit_Framework_Assert::assertContains(
142
            $value,
143
            $text = $this->findHeader($header)->getText(),
144
            sprintf('The grid column header "%s" does not contain "%s", got "%s".', $header, $value, $text)
145
        );
146
    }
147
148
    /**
149
     * @param bool $checked
150
     */
151
    public function assertBatchesState($checked)
152
    {
153
        $xpath = '/tr/td[1]/input';
154
155
        foreach ($this->findGrid()->findAll('xpath', $xpath) as $batch) {
156
            \PHPUnit_Framework_Assert::assertSame(
157
                $checked,
158
                $batch->isChecked(),
159
                sprintf('The grid batch "%s" should %s checked.', $batch->getValue(), $checked ? 'be' : 'not be')
160
            );
161
        }
162
    }
163
164
    /**
165
     * @param string[][] $rows
166
     */
167
    public function assertBody(array $rows)
168
    {
169
        foreach ($rows as $row => $columns) {
170
            $this->assertRow($row + 1, $columns);
171
        }
172
    }
173
174
    /**
175
     * @param int      $row
176
     * @param string[] $columns
177
     */
178 View Code Duplication
    public function assertRow($row, array $columns)
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...
179
    {
180
        $offset = $this->hastBatch() ? 2 : 1;
181
182
        foreach ($columns as $column => $value) {
183
            $this->assertCell($row, $column + $offset, $value);
184
        }
185
    }
186
187
    /**
188
     * @param string[] $header
189
     * @param string[] $cells
190
     */
191
    public function assertColumnCells($header, array $cells)
192
    {
193
        $column = $this->findHeaderIndex($header);
0 ignored issues
show
Documentation introduced by
$header is of type array<integer,string>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
194
        $offset = $this->hastBatch() ? 1 : 0;
195
196
        foreach ($cells as $row => $value) {
197
            $this->assertCell($row + 1, $column + $offset, $value);
198
        }
199
    }
200
201
    /**
202
     * @param int    $row
203
     * @param int    $column
204
     * @param string $value
205
     */
206
    public function assertCell($row, $column, $value)
207
    {
208
        \PHPUnit_Framework_Assert::assertContains(
209
            $value,
210
            $text = $this->findCell($row, $column)->getText(),
211
            sprintf(
212
                'The grid column body "%s" does not contain "%s at position %d, %d".',
213
                $text,
214
                $value,
215
                $row,
216
                $column
217
            )
218
        );
219
    }
220
221
    /**
222
     * @param string $header
223
     * @param string $sort
224
     */
225
    public function assertSorting($header, $sort)
226
    {
227
        $index = $this->findHeaderIndex($header);
228
229
        $values = $sortedValues = array_map(function (NodeElement $node) {
230
            return $node->getText();
231
        }, $this->findCell(null, $index));
232
233
        array_multisort($sortedValues, $sort === 'ASC' ? SORT_ASC : SORT_DESC);
234
235
        \PHPUnit_Framework_Assert::assertSame(
236
            $sortedValues,
237
            $values,
238
            sprintf(
239
                'The grid sorting does not match for the column "%s". Expected "%s", got "%s".',
240
                $header,
241
                json_encode($sortedValues),
242
                json_encode($values)
243
            )
244
        );
245
    }
246
247
    /**
248
     * @return bool
249
     */
250
    public function hastBatch()
251
    {
252
        try {
253
            $this->findBatch();
254
255
            return true;
256
        } catch (\PHPUnit_Framework_ExpectationFailedException $e) {
257
            return false;
258
        }
259
    }
260
261
    /**
262
     * @param string|null $cell
263
     *
264
     * @return NodeElement
265
     */
266
    public function findBatch($cell = null)
267
    {
268
        if ($cell === null) {
269
            \PHPUnit_Framework_Assert::assertNotNull(
270
                $batch = $this->findHeader(1)->find('xpath', '/input'),
271
                'The grid toggle batch checkbox could not be found.'
272
            );
273
274
            return $batch;
275
        }
276
277
        $xpath = '/../td[1]/input';
278
279
        \PHPUnit_Framework_Assert::assertNotNull(
280
            $batch = $this->findCell(null, null, $cell)->find('xpath', $xpath),
281
            sprintf('The grid column batch checkbox of the cell "%s" could not be found.', $cell)
282
        );
283
284
        return $batch;
285
    }
286
287
    /**
288
     * @param string $header
289
     *
290
     * @return int
291
     */
292
    public function findHeaderIndex($header)
293
    {
294
        $xpath = $this->findHeader($header)->getXpath().'/preceding::*';
295
296
        return count($this->getPage()->findAll('xpath', $xpath)) + 1;
297
    }
298
299
    /**
300
     * @param string|int $header
301
     *
302
     * @return NodeElement
303
     */
304
    public function findHeader($header)
305
    {
306
        $xpath = '/thead/tr/th'.(is_int($header) ? '['.$header.']' : '[contains(text(), "'.$header.'")]');
307
308
        \PHPUnit_Framework_Assert::assertNotNull(
309
            $node = $this->findGrid()->find('xpath', $xpath),
310
            sprintf('The grid header "%s" could not be found.', $header)
311
        );
312
313
        return $node;
314
    }
315
316
    /**
317
     * @param int|null    $row
318
     * @param int|null    $column
319
     * @param string|null $value
320
     *
321
     * @return NodeElement|NodeElement[]
322
     */
323
    public function findCell($row = null, $column = null, $value = null)
324
    {
325
        $rowXPath = $row;
326
        $columnXPath = $column;
327
        $valueXPath = $value;
328
329
        if ($row !== null) {
330
            $rowXPath = '['.$row.']';
331
        }
332
333
        if ($column !== null) {
334
            $columnXPath = '['.$column.']';
335
        }
336
337
        if ($value !== null) {
338
            $valueXPath = '[contains(text(), "'.$value.'")]';
339
        }
340
341
        $xpath = '/tbody/tr'.$rowXPath.'/td'.$columnXPath.$valueXPath;
342
343
        if ($value !== null || ($row !== null && $column !== null)) {
344
            \PHPUnit_Framework_Assert::assertNotNull(
345
                $cell = $this->findGrid()->find('xpath', $xpath),
346
                sprintf(
347
                    'The grid cell could not be found (row: %s, column: %s, value: %s).',
348
                    $row !== null ? $row : 'none',
349
                    $column !== null ? $column : 'none',
350
                    $value !== null ? $value : 'none'
351
                )
352
            );
353
354
            return $cell;
355
        }
356
357
        return $this->findGrid()->findAll('xpath', $xpath);
358
    }
359
360
    /**
361
     * @return NodeElement
362
     */
363
    public function findGrid()
364
    {
365
        $xpath = '//section[contains(@class, "content")]//table';
366
367
        \PHPUnit_Framework_Assert::assertNotNull(
368
            $grid = $this->getPage()->find('xpath', $xpath),
369
            'The grid could not be found.'
370
        );
371
372
        return $grid;
373
    }
374
}
375