Completed
Push — master ( 311854...50994d )
by Andrii
20:37 queued 05:34
created

Grid::openRowMenuById()   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
    /**
137
     * Opens table row menu by its number.
138
     *
139
     * @param int $n - number of the row which menu should be opened
140
     */
141
    public function openRowMenuByNumber(int $n): void
142
    {
143
        $selector = $this->baseSelector . "//tbody//tr[{$n}]//" .
144
                    self::MENU_BUTTON_SELECTOR;
145
146
        $this->tester->click($selector);
147
    }
148
149
    /**
150
     * Opens table row menu by item id (data-key).
151
     *
152
     * @param string $id - id of item which menu should be opened
153
     */
154
    public function openRowMenuById(string $id): void
155
    {
156
        $selector = $this->baseSelector . "//tbody//tr[@data-key={$id}]//" .
157
                    self::MENU_BUTTON_SELECTOR;
158
159
        $this->tester->click($selector);
160
    }
161
162
    /**
163
     * Opens table row menu by the column name and value in it.
164
     *
165
     * ```php
166
     *  $indexPage->openRowMenuByColumnValue('Name', 'test_item');
167
     * ```
168
     * Will open the menu for the row, which has value 'test_item' in column 'Name'.
169
     *
170
     * @param string $column
171
     * @param string $value
172
     * @throws \Codeception\Exception\ModuleException
173
     */
174
    public function openRowMenuByColumnValue(string $column, string $value): void
175
    {
176
        $setSelector = 'thead th';
177
        $elementSelector = "th:contains('{$column}')";
178
179
        $elementIndex = $this->tester->indexOf($elementSelector, $setSelector);
180
        $elementIndex++;
181
182
        $selector = "//tr//td[{$elementIndex}]/descendant-or-self::" .
183
            "*[contains(text(), '{$value}')]//ancestor::tr";
184
        $rowId = $this->tester->grabAttributeFrom($selector, 'data-key');
185
186
        $this->openRowMenuById($rowId);
187
    }
188
189
    /**
190
     * Clicks to the specified row menu option.
191
     *
192
     * @param $option - the name of option that should be clicked
193
     * @throws \Codeception\Exception\ModuleException
194
     */
195
    public function chooseRowMenuOption(string $option): void
196
    {
197
        $selector = "//div[contains(@class, 'popover')]" .
198
            "//a[contains(text(), '{$option}')]";
199
        $this->tester->click($selector);
200
        $this->tester->waitForPageUpdate();
201
    }
202
203
    /**
204
     * Returns amount of rows in table.
205
     *
206
     * @return int
207
     */
208
    public function countRowsInTableBody(): int
209
    {
210
        return count($this->tester->grabMultiple('//tbody/tr[contains(@data-key,*)]'));
211
    }
212
213
    /**
214
     * Checks whether sorting works properly.
215
     *
216
     * Method find column by $sortBy, parse data, call default sort by $sortBy
217
     * and compare data in table with sort(copy_data_from_table)
218
     *
219
     * @param string $sortBy
220
     * @throws \Codeception\Exception\ModuleException
221
     */
222
    public function checkSortingBy(string $sortBy): void
223
    {
224
        $this->tester->click("//button[contains(text(),'Sort')]");
225
        $this->tester->click("//ul//a[contains(text(),'$sortBy')]");
226
        $this->tester->waitForPageUpdate();
227
        $tableWithNeedle = $this->tester->grabMultiple('//th/a');
228
        $whereNeedle = 0;
229
        $count = $this->countRowsInTableBody();
230
        while ($whereNeedle < count($tableWithNeedle)) {
231
            if ($tableWithNeedle[$whereNeedle] === $sortBy) {
232
                break;
233
            }
234
            ++$whereNeedle;
235
        }
236
        $whereNeedle += 2;
237
        /**
238
         *  $whereNeedle += 2 && $i = 1 because xpath elements starting from 1.
239
         */
240
        $arrayForSort = [];
241 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...
242
            $arrayForSort[$i] = $this->tester->grabTextFrom("//tbody/tr[$i]/td[$whereNeedle]");
243
        }
244
        /**
245
         *  After sort() function arrayForSort start index = 0, but xpath elements starting from 1.
246
         */
247
        sort($arrayForSort, SORT_NATURAL | SORT_FLAG_CASE);
248 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...
249
            $this->tester->see($arrayForSort[$i - 1], "//tbody/tr[$i]/td[$whereNeedle]");
250
        }
251
    }
252
}
253