1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace hipanel\tests\_support\Page; |
4
|
|
|
|
5
|
|
|
use hipanel\tests\_support\Page\Widget\Input\Input; |
6
|
|
|
use hipanel\tests\_support\Page\Widget\Input\TestableInput; |
7
|
|
|
use hipanel\tests\_support\Page\Widget\Input\Dropdown; |
8
|
|
|
|
9
|
|
|
use WebDriverKeys; |
10
|
|
|
|
11
|
|
|
class IndexPage extends Authenticated |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* @param TestableInput[] $inputs example: |
15
|
|
|
* ```php |
16
|
|
|
* [ |
17
|
|
|
* Input::asAdvancedSearch(Tester, 'Name'), |
18
|
|
|
* Select2::asAdvancedSearch(Tester, 'Status') |
19
|
|
|
* ] |
20
|
|
|
*``` |
21
|
|
|
*/ |
22
|
|
|
public function containsFilters(array $inputs): void |
23
|
|
|
{ |
24
|
|
|
$I = $this->tester; |
25
|
|
|
|
26
|
|
|
$I->see('Advanced search', 'h3'); |
27
|
|
|
|
28
|
|
|
foreach ($inputs as $input) { |
29
|
|
|
$input->isVisible(); |
30
|
|
|
} |
31
|
|
|
$I->see('Search', TestableInput::AS_BASE . "button[type='submit']"); |
32
|
|
|
$I->see('Clear', TestableInput::AS_BASE . "a"); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param string[] $list array of legend list |
37
|
|
|
*/ |
38
|
|
|
public function containsLegend(array $list): void |
39
|
|
|
{ |
40
|
|
|
$I = $this->tester; |
41
|
|
|
|
42
|
|
|
$I->see('Legend', 'h3'); |
43
|
|
|
|
44
|
|
|
foreach ($list as $text) { |
45
|
|
|
$I->see($text, "//h3[text()='Legend']/../../div/ul/li"); |
46
|
|
|
} |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @param string[] $buttons array of buttons |
51
|
|
|
*/ |
52
|
|
|
public function containsBulkButtons(array $buttons): void |
53
|
|
|
{ |
54
|
|
|
$I = $this->tester; |
55
|
|
|
|
56
|
|
|
foreach ($buttons as $text) { |
57
|
|
|
$I->see($text, "//button[@type='submit' or @type='button']"); |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param string[] $columnNames array of column names |
63
|
|
|
* @param string|null $representation the representation name |
64
|
|
|
* @throws \Codeception\Exception\ModuleException |
65
|
|
|
*/ |
66
|
|
|
public function containsColumns(array $columnNames, $representation = null): void |
67
|
|
|
{ |
68
|
|
|
$I = $this->tester; |
69
|
|
|
$formId = $I->grabAttributeFrom("//form[contains(@id, 'bulk') " . |
70
|
|
|
"and contains(@id, 'search')]", 'id'); |
71
|
|
|
|
72
|
|
|
if ($representation !== null) { |
73
|
|
|
$I->click("//button[contains(text(), 'View:')]"); |
74
|
|
|
$I->click("//ul/li/a[contains(text(), '$representation')]"); |
75
|
|
|
$I->waitForPageUpdate(120); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
foreach ($columnNames as $column) { |
79
|
|
|
$I->see($column, "//form[@id='$formId']//table/thead/tr/th"); |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @param int $amount |
85
|
|
|
*/ |
86
|
|
|
public function containsAmountOfRows(int $amount): void |
87
|
|
|
{ |
88
|
|
|
$this->tester->seeNumberOfElements('//tbody/tr', $amount); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public function getRowDataKeyByNumber(int $rowNumber): string |
92
|
|
|
{ |
93
|
|
|
$selector = "form tbody tr:nth-child($rowNumber)"; |
94
|
|
|
|
95
|
|
|
return $this->tester->grabAttributeFrom($selector, 'data-key'); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Filters index page table |
100
|
|
|
* |
101
|
|
|
* @param TestableInput $inputElement |
102
|
|
|
* @param $value |
103
|
|
|
* @throws \Codeception\Exception\ModuleException |
104
|
|
|
*/ |
105
|
|
|
public function filterBy(TestableInput $inputElement, string $value): void |
106
|
|
|
{ |
107
|
|
|
$inputElement->setValue($value); |
108
|
|
|
if ($inputElement instanceof Input) { |
109
|
|
|
$this->tester->pressKey($inputElement->getSelector(),WebDriverKeys::ENTER); |
110
|
|
|
} |
111
|
|
|
$this->tester->wait(1); |
112
|
|
|
$this->tester->waitForPageUpdate(); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Selects table row by its number |
117
|
|
|
* |
118
|
|
|
* @param int $n - number of the row that should be selected |
119
|
|
|
*/ |
120
|
|
|
public function selectTableRowByNumber(int $n): void |
121
|
|
|
{ |
122
|
|
|
$I = $this->tester; |
123
|
|
|
|
124
|
|
|
$selector = "form tbody tr:nth-child($n) input[type=checkbox]"; |
125
|
|
|
$I->click($selector); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Opens table row menu by its number |
130
|
|
|
* |
131
|
|
|
* @param int $n - number of the row which menu should be opened |
132
|
|
|
*/ |
133
|
|
|
public function openRowMenuByNumber(int $n): void |
134
|
|
|
{ |
135
|
|
|
$this->tester->click("form tbody tr:nth-child($n) button"); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Opens table row menu by item id |
140
|
|
|
* |
141
|
|
|
* @param string $id - id of item which menu should be opened |
142
|
|
|
*/ |
143
|
|
|
public function openRowMenuById(string $id): void |
144
|
|
|
{ |
145
|
|
|
$this->tester->click("tr[data-key='$id'] button"); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Clicks to row menu option |
150
|
|
|
* |
151
|
|
|
* @param $option - the name of option that should be clicked |
152
|
|
|
* @throws \Codeception\Exception\ModuleException |
153
|
|
|
*/ |
154
|
|
|
public function chooseRowMenuOption(string $option): void |
155
|
|
|
{ |
156
|
|
|
$this->tester->click("//ul[@class='nav']//a[contains(text(), '{$option}')]"); |
157
|
|
|
$this->tester->waitForPageUpdate(); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Parse tbody, count td and return result |
162
|
|
|
* |
163
|
|
|
* @return int |
164
|
|
|
*/ |
165
|
|
|
public function countRowsInTableBody(): int |
166
|
|
|
{ |
167
|
|
|
return count($this->tester->grabMultiple('//tbody/tr[contains(@data-key,*)]')); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Checks whether filtering works properly |
172
|
|
|
* |
173
|
|
|
* @param string $filterBy |
174
|
|
|
* @param string $name |
175
|
|
|
* @throws \Codeception\Exception\ModuleException |
176
|
|
|
*/ |
177
|
|
|
public function checkFilterBy(string $filterBy, string $name): void |
178
|
|
|
{ |
179
|
|
|
$this->filterBy(new Dropdown($this->tester, "tr.filters select[name*=$filterBy]"), $name); |
180
|
|
|
$count = $this->countRowsInTableBody(); |
181
|
|
|
for ($i = 1 ; $i <= $count; ++$i) { |
182
|
|
|
$this->tester->see($name, "//tbody/tr[$i]"); |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Checks whether sorting works properly |
188
|
|
|
* |
189
|
|
|
* Method find column by $sortBy, parse data, call default sort by $sortBy |
190
|
|
|
* and compare data in table with sort(copy_data_from_table) |
191
|
|
|
* |
192
|
|
|
* @param string $sortBy |
193
|
|
|
* @throws \Codeception\Exception\ModuleException |
194
|
|
|
*/ |
195
|
|
|
public function checkSortingBy(string $sortBy): void |
196
|
|
|
{ |
197
|
|
|
$this->tester->click("//button[contains(text(),'Sort')]"); |
198
|
|
|
$this->tester->click("//ul//a[contains(text(),'$sortBy')]"); |
199
|
|
|
$this->tester->waitForPageUpdate(); |
200
|
|
|
$tableWithNeedle = $this->tester->grabMultiple('//th/a'); |
201
|
|
|
$whereNeedle = 0; |
202
|
|
|
$count = $this->countRowsInTableBody(); |
203
|
|
|
while ($whereNeedle < count($tableWithNeedle)) { |
204
|
|
|
if ($tableWithNeedle[$whereNeedle] === $sortBy) { |
205
|
|
|
break ; |
206
|
|
|
} |
207
|
|
|
$whereNeedle++; |
208
|
|
|
} |
209
|
|
|
$whereNeedle += 2; |
210
|
|
|
/** |
211
|
|
|
* $whereNeedle += 2 && $i = 1 because xpath elements starting from 1 |
212
|
|
|
*/ |
213
|
|
|
$arrayForSort = []; |
214
|
|
View Code Duplication |
for ($i = 1 ; $i <= $count; ++$i) { |
|
|
|
|
215
|
|
|
$arrayForSort[$i] = $this->tester->grabTextFrom("//tbody/tr[$i]/td[$whereNeedle]"); |
216
|
|
|
} |
217
|
|
|
/** |
218
|
|
|
* After sort() function arrayForSort start index = 0, but xpath elements starting from 1 |
219
|
|
|
*/ |
220
|
|
|
sort($arrayForSort, SORT_NATURAL | SORT_FLAG_CASE); |
221
|
|
View Code Duplication |
for ($i = 1 ; $i <= $count; ++$i) { |
|
|
|
|
222
|
|
|
$this->tester->see($arrayForSort[$i - 1], "//tbody/tr[$i]/td[$whereNeedle]"); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
|
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.