Completed
Push — master ( 50994d...9672d9 )
by Dmitry
27:16 queued 12:18
created

Grid::selectRowById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * HiPanel core package
4
 *
5
 * @link      https://hipanel.com/
6
 * @package   hipanel-core
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2014-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\tests\_support\Page\Widget;
12
13
use hipanel\tests\_support\AcceptanceTester;
14
use hipanel\tests\_support\Page\Widget\Input\Input;
15
use hipanel\tests\_support\Page\Widget\Input\TestableInput;
16
use WebDriverKeys;
17
18
/**
19
 * Class Grid
20
 *
21
 * Represents GridView
22
 * @package hipanel\tests\_support\Page\Widget
23
 */
24
class Grid
25
{
26
    /** @var string $baseSelector selector of current gridView */
27
    private $baseSelector = "//form[contains(@id, 'bulk')]";
28
29
    /** @var AcceptanceTester */
30
    private $tester;
31
32
    const MENU_BUTTON_SELECTOR = "button[contains(@data-popover-content, '#menu')]";
33
34
    const ROW_CHECKBOX_SELECTOR = "input[contains(@class, 'grid-checkbox')]";
35
36
    /**
37
     * Grid constructor.
38
     * @param AcceptanceTester $tester
39
     * @param string|null $baseSelector
40
     */
41
    public function __construct(AcceptanceTester $tester, string $baseSelector = null)
42
    {
43
        $this->tester = $tester;
44
        if (!is_null($baseSelector)) {
45
            $this->baseSelector = $baseSelector;
46
        }
47
    }
48
49
    /**
50
     * Checks whether current table representation contains specified columns.
51
     *
52
     * @param string[] $columnNames array of column names
53
     * @param string|null $representation the representation name
54
     * @throws \Codeception\Exception\ModuleException
55
     */
56
    public function containsColumns(array $columnNames, $representation = null): void
57
    {
58
        $I = $this->tester;
59
        $formId = $I->grabAttributeFrom($this->baseSelector, 'id');
60
61
        if ($representation !== null) {
62
            $I->click("//button[contains(text(), 'View:')]");
63
            $I->click("//ul/li/a[contains(text(), '$representation')]");
64
            $I->waitForPageUpdate();
65
        }
66
67
        foreach ($columnNames as $column) {
68
            $I->see($column, "//form[@id='$formId']//table/thead/tr/th");
69
        }
70
    }
71
72
    /**
73
     * Filters gridView by specified value.
74
     *
75
     * @param TestableInput $inputElement
76
     * @param string $value
77
     * @throws \Codeception\Exception\ModuleException
78
     */
79
    public function filterBy(TestableInput $inputElement, string $value): void
80
    {
81
        $inputElement->setValue($value);
82
        if ($inputElement instanceof Input) {
83
            $this->tester->pressKey($inputElement->getSelector(), WebDriverKeys::ENTER);
84
        }
85
        $this->tester->waitForPageUpdate();
86
    }
87
88
    /**
89
     * Sorts grid by specified column.
90
     *
91
     * @param string $columnName
92
     * @throws \Codeception\Exception\ModuleException
93
     */
94
    public function sortBy(string $columnName): void
95
    {
96
        $this->tester->click("//th/a[contains(text(), '$columnName')]");
97
        $this->tester->waitForPageUpdate();
98
    }
99
100
    /**
101
     * Checks amount of the data rows in the table.
102
     *
103
     * @param int $amount
104
     */
105
    public function containsAmountOfRows(int $amount): void
106
    {
107
        $this->tester->seeNumberOfElements($this->baseSelector . '//tbody/tr', $amount);
108
    }
109
110
    /**
111
     * Returns data-key value for specified row in the table.
112
     *
113
     * @param int $rowNumber - number of the row in the table
114
     * @return string
115
     */
116
    public function getRowDataKeyByNumber(int $rowNumber): string
117
    {
118
        $selector = $this->baseSelector . "//tbody//tr[${$rowNumber}]";
119
120
        return $this->tester->grabAttributeFrom($selector, 'data-key');
121
    }
122
123
    /**
124
     * Selects table row by its number.
125
     *
126
     * @param int $n - number of the row that should be selected
127
     */
128
    public function selectRowByNumber(int $n): void
129
    {
130
        $selector = $this->baseSelector . "//tbody//tr[{$n}]//" .
131
                    self::ROW_CHECKBOX_SELECTOR;
132
133
        $this->tester->click($selector);
134
    }
135
136
    public function selectRowById(int $id): void
137
    {
138
        $selector = $this->baseSelector . "//tbody//tr[@data-key={$id}]//" .
139
            self::ROW_CHECKBOX_SELECTOR;
140
141
        $this->tester->click($selector);
142
    }
143
144
    /**
145
     * Opens table row menu by its number.
146
     *
147
     * @param int $n - number of the row which menu should be opened
148
     */
149
    public function openRowMenuByNumber(int $n): void
150
    {
151
        $selector = $this->baseSelector . "//tbody//tr[{$n}]//" .
152
                    self::MENU_BUTTON_SELECTOR;
153
154
        $this->tester->click($selector);
155
    }
156
157
    /**
158
     * Opens table row menu by item id (data-key).
159
     *
160
     * @param string $id - id of item which menu should be opened
161
     */
162
    public function openRowMenuById(string $id): void
163
    {
164
        $selector = $this->baseSelector . "//tbody//tr[@data-key={$id}]//" .
165
                    self::MENU_BUTTON_SELECTOR;
166
167
        $this->tester->click($selector);
168
    }
169
170
    /**
171
     * Opens table row menu by the column name and value in it.
172
     *
173
     * ```php
174
     *  $indexPage->openRowMenuByColumnValue('Name', 'test_item');
175
     * ```
176
     * Will open the menu for the row, which has value 'test_item' in column 'Name'.
177
     *
178
     * @param string $column
179
     * @param string $value
180
     * @throws \Codeception\Exception\ModuleException
181
     */
182
    public function openRowMenuByColumnValue(string $column, string $value): void
183
    {
184
        $setSelector = 'thead th';
185
        $elementSelector = "th:contains('{$column}')";
186
187
        $elementIndex = $this->tester->indexOf($elementSelector, $setSelector);
188
        $elementIndex++;
189
190
        $selector = "//tr//td[{$elementIndex}]/descendant-or-self::" .
191
            "*[contains(text(), '{$value}')]//ancestor::tr";
192
        $rowId = $this->tester->grabAttributeFrom($selector, 'data-key');
193
194
        $this->openRowMenuById($rowId);
195
    }
196
197
    /**
198
     * Clicks to the specified row menu option.
199
     *
200
     * @param $option - the name of option that should be clicked
201
     * @throws \Codeception\Exception\ModuleException
202
     */
203
    public function chooseRowMenuOption(string $option): void
204
    {
205
        $selector = "//div[contains(@class, 'popover')]" .
206
            "//a[contains(text(), '{$option}')]";
207
        $this->tester->click($selector);
208
        $this->tester->waitForPageUpdate();
209
    }
210
211
    /**
212
     * Returns amount of rows in table.
213
     *
214
     * @return int
215
     */
216
    public function countRowsInTableBody(): int
217
    {
218
        return count($this->tester->grabMultiple('//tbody/tr[contains(@data-key,*)]'));
219
    }
220
221
    /**
222
     * Checks whether sorting works properly.
223
     *
224
     * Method find column by $sortBy, parse data, call default sort by $sortBy
225
     * and compare data in table with sort(copy_data_from_table)
226
     *
227
     * @param string $sortBy
228
     * @throws \Codeception\Exception\ModuleException
229
     */
230
    public function checkSortingBy(string $sortBy): void
231
    {
232
        $this->tester->click("//button[contains(text(),'Sort')]");
233
        $this->tester->click("//ul//a[contains(text(),'$sortBy')]");
234
        $this->tester->waitForPageUpdate();
235
        $tableWithNeedle = $this->tester->grabMultiple('//th/a');
236
        $whereNeedle = 0;
237
        $count = $this->countRowsInTableBody();
238
        while ($whereNeedle < count($tableWithNeedle)) {
239
            if ($tableWithNeedle[$whereNeedle] === $sortBy) {
240
                break;
241
            }
242
            ++$whereNeedle;
243
        }
244
        $whereNeedle += 2;
245
        /**
246
         *  $whereNeedle += 2 && $i = 1 because xpath elements starting from 1.
247
         */
248
        $arrayForSort = [];
249 View Code Duplication
        for ($i = 1; $i <= $count; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
250
            $arrayForSort[$i] = $this->tester->grabTextFrom("//tbody/tr[$i]/td[$whereNeedle]");
251
        }
252
        /**
253
         *  After sort() function arrayForSort start index = 0, but xpath elements starting from 1.
254
         */
255
        sort($arrayForSort, SORT_NATURAL | SORT_FLAG_CASE);
256 View Code Duplication
        for ($i = 1; $i <= $count; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
257
            $this->tester->see($arrayForSort[$i - 1], "//tbody/tr[$i]/td[$whereNeedle]");
258
        }
259
    }
260
}
261