Passed
Push — develop ( 6bfba2...d35452 )
by Nikolay
05:12
created

MikoPBXTestsBase::selectDropdownItem()   B

Complexity

Conditions 7
Paths 91

Size

Total Lines 44
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 32
c 0
b 0
f 0
dl 0
loc 44
rs 8.4746
cc 7
nc 91
nop 2
1
<?php
2
/**
3
 * Copyright (C) MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Nikolay Beketov, 5 2020
7
 *
8
 */
9
10
namespace MikoPBX\Tests\AdminCabinet\Lib;
11
12
use Exception;
13
use Facebook\WebDriver\Exception\NoSuchElementException;
14
use Facebook\WebDriver\Exception\TimeoutException;
15
use Facebook\WebDriver\Interactions\WebDriverActions;
16
use Facebook\WebDriver\WebDriverBy;
17
use Facebook\WebDriver\WebDriverExpectedCondition;
18
use MikoPBX\Tests\AdminCabinet\Tests\LoginTrait;
19
20
21
class MikoPBXTestsBase extends BrowserStackTest
22
{
23
    use  LoginTrait;
24
25
    /**
26
     * Assert that menu item not found on the page
27
     *
28
     * @param $by
29
     */
30
    protected function assertElementNotFound($by): void
31
    {
32
        $els = self::$driver->findElements($by);
33
        if (count($els)) {
34
            $this->fail("Unexpectedly element was found by " . $by . PHP_EOL);
35
        }
36
        // increment assertion counter
37
        $this->assertTrue(true);
38
    }
39
40
    /**
41
     * Select dropdown menu item
42
     *
43
     * @param $name  string menu name identifier
44
     * @param $value string menu value for select
45
     *
46
     */
47
    protected function selectDropdownItem(string $name, string $value): void
48
    {
49
        // Check selected value
50
        $xpath             = '//select[@name="' . $name . '"]/option[@selected="selected"]';
51
        $selectedExtensions = self::$driver->findElements(WebDriverBy::xpath($xpath));
52
        foreach ($selectedExtensions as $element) {
53
            $currentValue = $element->getAttribute('value');
54
            if ($currentValue === $value){
55
                return;
56
            }
57
        }
58
59
        $xpath = '//select[@name="' . $name . '"]/ancestor::div[contains(@class, "ui") and contains(@class ,"dropdown")]';
60
        $xpath .='| //div[@id="' . $name . '" and contains(@class, "ui") and contains(@class ,"dropdown") ]';
61
        try {
62
            $selectItem = self::$driver->findElement(WebDriverBy::xpath($xpath));
63
            $selectItem->click();
64
            $this->waitForAjax();
65
66
            // If search field exists input them before select
67
            $xpath = '//select[@name="' . $name . '"]/ancestor::div[contains(@class, "ui") and contains(@class ,"dropdown")]/input[contains(@class,"search")]';
68
            $xpath .='| //div[@id="' . $name . '" and contains(@class, "ui") and contains(@class ,"dropdown") ]/input[contains(@class,"search")]';
69
            $inputItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
70
            $actions = new WebDriverActions(self::$driver);
71
            foreach ($inputItems as $inputItem) {
72
                $actions->moveToElement($inputItem);
73
                $actions->perform();
74
                $inputItem->click();
75
                $inputItem->clear();
76
                $inputItem->sendKeys($value);
77
            }
78
79
            // Находим строчку с нужной опцией по значению
80
            $xpath    = '//div[contains(@class, "menu") and contains(@class ,"visible")]/div[@data-value="' . $value . '"]';
81
            $menuItem = self::$driver->wait()->until(
82
                WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::xpath($xpath))
83
            );
84
            $menuItem->click();
85
        } catch (NoSuchElementException $e) {
86
            $this->fail('Not found select with name ' . $name . 'on selectDropdownItem'. PHP_EOL);
87
        } catch (TimeoutException $e) {
88
            $this->fail('Not found menuitem ' . $value . PHP_EOL);
89
        } catch (Exception $e) {
90
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
91
        }
92
    }
93
94
    /**
95
     * Wait until jquery will be ready
96
     */
97
    protected function waitForAjax(): void
98
    {
99
        while (true) // Handle timeout somewhere
100
        {
101
            $ajaxIsComplete = (bool)(self::$driver->executeScript("return jQuery.active == 0"));
102
            if ($ajaxIsComplete) {
103
                break;
104
            }
105
            sleep(1);
106
        }
107
    }
108
109
    /**
110
     * Assert that menu item selected
111
     *
112
     * @param      $name         string menu name
113
     * @param      $checkedValue string checked value
114
     * @param bool $skipIfNotExist
115
     */
116
    protected function assertMenuItemSelected(string $name, string $checkedValue, $skipIfNotExist=false): void
117
    {
118
        $xpath             = '//select[@name="' . $name . '"]/option[@selected="selected"]';
119
        if ($checkedValue==='none'){
120
            $this->assertElementNotFound(WebDriverBy::xpath($xpath));
121
        } else {
122
            $selectedExtensions = self::$driver->findElements(WebDriverBy::xpath($xpath));
123
            foreach ($selectedExtensions as $element) {
124
                $currentValue = $element->getAttribute('value');
125
                $message      = "{$name} check failure, because {$checkedValue} != {$currentValue}";
126
                $this->assertEquals($checkedValue, $currentValue, $message);
127
            }
128
            if (!$skipIfNotExist && count($selectedExtensions)===0){
129
                $this->fail('Not found select with name ' . $name .' in assertMenuItemSelected'. PHP_EOL);
130
            }
131
        }
132
    }
133
134
    /**
135
     * Change textarea with name $name value to $value
136
     *
137
     * @param string $name
138
     * @param string $value
139
     * @param bool   $skipIfNotExist
140
     */
141
    protected function changeTextAreaValue(string $name, string $value, bool $skipIfNotExist=false): void
142
    {
143
        $xpath         = ('//textarea[@name="' . $name . '"]');
144
        $textAreaItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
145
        $actions = new WebDriverActions(self::$driver);
146
        foreach ($textAreaItems as $textAreaItem) {
147
            $actions->moveToElement($textAreaItem);
148
            $actions->perform();
149
            $textAreaItem->click();
150
            $textAreaItem->clear();
151
            $textAreaItem->sendKeys($value);
152
        }
153
        if (!$skipIfNotExist && count($textAreaItems)===0){
154
            $this->fail('Not found textarea with name ' . $name .' in changeTextAreaValue'. PHP_EOL);
155
        }
156
    }
157
158
    /**
159
     * Assert that textArea value is equal
160
     *
161
     * @param string $name         textArea name
162
     * @param string $checkedValue checked value
163
     */
164
    protected function assertTextAreaValueIsEqual(string $name, string $checkedValue): void
165
    {
166
        $xpath        = '//textarea[@name="' . $name . '"]';
167
        $textAreaItem = self::$driver->findElement(WebDriverBy::xpath($xpath));
168
        $currentValue = $textAreaItem->getAttribute('value');
169
        $message      = "{$name} check failure, because {$checkedValue} != {$currentValue}";
170
        $this->assertEquals($checkedValue, $currentValue, $message);
171
    }
172
173
    /**
174
     * If file filed with $name exists on the page, it value will be changed on $value
175
     *
176
     * @param string $name
177
     * @param string $value
178
     * @param bool   $skipIfNotExist
179
     */
180
    protected function changeFileField(string $name, string $value, bool $skipIfNotExist=false): void
181
    {
182
        $xpath      = '//input[@name="' . $name . '" and (@type = "file")]';
183
        $inputItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
184
        foreach ($inputItems as $inputItem) {
185
            $inputItem->sendKeys($value);
186
        }
187
        if (!$skipIfNotExist && count($inputItems)===0){
188
            $this->fail('Not found input with type FILE and with name ' . $name .' in changeFileField'. PHP_EOL);
189
        }
190
    }
191
192
    /**
193
     * If input filed with $name exists on the page, it value will be changed on $value
194
     *
195
     * @param string $name
196
     * @param string $value
197
     * @param bool   $skipIfNotExist
198
     */
199
    protected function changeInputField(string $name, string $value, bool $skipIfNotExist=false): void
200
    {
201
        $xpath      = '//input[@name="' . $name . '" and (@type="text" or @type="password" or @type="hidden" or @type="number")]';
202
        $inputItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
203
        $actions = new WebDriverActions(self::$driver);
204
        foreach ($inputItems as $inputItem) {
205
            $actions->moveToElement($inputItem);
206
            $actions->perform();
207
            $id = $inputItem->getAttribute('id');
208
            if (!empty($id)){
209
                self::$driver->executeScript("document.getElementById('{$id}').scrollIntoView({block: 'center'})");
210
            }
211
            $inputItem->click();
212
            $inputItem->clear();
213
            $inputItem->sendKeys($value);
214
        }
215
        if (!$skipIfNotExist && count($inputItems)===0){
216
            $this->fail('Not found input with name ' . $name .' in changeInputField'. PHP_EOL);
217
        }
218
    }
219
220
    /**
221
     * Assert that input field with name $name value is equal to $checkedValue
222
     *
223
     * @param string $name
224
     * @param string $checkedValue
225
     * @param bool   $skipIfNotExist
226
     */
227
    protected function assertInputFieldValueEqual(string $name, string $checkedValue, $skipIfNotExist=false): void
228
    {
229
        $xpath      = '//input[@name="' . $name . '" and (@type="text" or @type="number" or @type="password" or @type="hidden")]';
230
        $inputItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
231
        foreach ($inputItems as $inputItem) {
232
            $currentValue = $inputItem->getAttribute('value');
233
            $message      = "input field: '{$name}' check failure, because {$checkedValue} != {$currentValue}";
234
            $this->assertEquals($checkedValue, $currentValue, $message);
235
        }
236
        if (!$skipIfNotExist && count($inputItems)===0){
237
            $this->fail('Not found input with name ' . $name .' in assertInputFieldValueEqual'. PHP_EOL);
238
        }
239
    }
240
241
    /**
242
     * Change checkbox state according the $enabled value if checkbox with the $name exist on the page
243
     *
244
     * @param string $name
245
     * @param bool   $enabled
246
     * @param bool   $skipIfNotExist
247
     */
248
    protected function changeCheckBoxState(string $name, bool $enabled, $skipIfNotExist=false): void
249
    {
250
        $xpath         = '//input[@name="' . $name . '" and @type="checkbox"]';
251
        $checkBoxItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
252
        foreach ($checkBoxItems as $checkBoxItem) {
253
            if (
254
                ($enabled && ! $checkBoxItem->isSelected())
255
                ||
256
                ( ! $enabled && $checkBoxItem->isSelected())
257
            ) {
258
                $xpath        = '//input[@name="' . $name . '" and @type="checkbox"]/parent::div';
259
                $checkBoxItem = self::$driver->findElement(WebDriverBy::xpath($xpath));
260
                $actions = new WebDriverActions(self::$driver);
261
                $actions->moveToElement($checkBoxItem);
262
                $actions->perform();
263
                $checkBoxItem->click();
264
            }
265
        }
266
        if (!$skipIfNotExist && count($checkBoxItems)===0){
267
            $this->fail('Not found checkbox with name ' . $name .' in changeCheckBoxState'. PHP_EOL);
268
        }
269
    }
270
271
    /**
272
     * Assert that checkBox state is equal to the $enabled if checkbox with the $name exist on the page
273
     *
274
     * @param string $name    checkBox name
275
     * @param bool   $enabled checked state
276
     * @param bool   $skipIfNotExist
277
     */
278
    protected function assertCheckBoxStageIsEqual(string $name, bool $enabled, $skipIfNotExist=false): void
279
    {
280
        $xpath         = '//input[@name="' . $name . '" and @type="checkbox"]';
281
        $checkBoxItems = self::$driver->findElements(WebDriverBy::xpath($xpath));
282
        foreach ($checkBoxItems as $checkBoxItem) {
283
            if ($enabled) {
284
                $this->assertTrue($checkBoxItem->isSelected(), "{$name} must be checked" . PHP_EOL);
285
            } else {
286
                $this->assertFalse($checkBoxItem->isSelected(), "{$name} must be unchecked" . PHP_EOL);
287
            }
288
        }
289
        if (!$skipIfNotExist && count($checkBoxItems)===0){
290
            $this->fail('Not found checkbox with name ' . $name .' in assertCheckBoxStageIsEqual'. PHP_EOL);
291
        }
292
    }
293
294
    /**
295
     * Submit form with id - $formId and wait until form send
296
     *
297
     * @param string $formId
298
     *
299
     */
300
    protected function submitForm(string $formId): void
301
    {
302
        $xpath = '//form[@id="' . $formId . '"]//ancestor::div[@id="submitbutton"]';
303
        try {
304
            $button_Submit = self::$driver->findElement(WebDriverBy::xpath($xpath));
305
            $actions = new WebDriverActions(self::$driver);
306
            $actions->moveToElement($button_Submit);
307
            $actions->perform();
308
            $button_Submit->click();
309
            $this->waitForAjax();
310
            self::$driver->wait(10, 500)->until(
311
                function ($driver) use ($xpath) {
312
                    $button_Submit = $driver->findElement(WebDriverBy::xpath($xpath));
313
314
                    return $button_Submit->isEnabled();
315
                }
316
            );
317
        } catch (NoSuchElementException $e) {
318
            $this->fail('Not found submit button on this page' . PHP_EOL);
319
        } catch (TimeoutException $e) {
320
            $this->fail('Form doesn\'t send after 10 seconds timeout' . PHP_EOL);
321
        } catch (Exception $e) {
322
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
323
        }
324
    }
325
326
    /**
327
     * Click on the left sidebar menu item
328
     *
329
     * @param string $href
330
     */
331
    protected function clickSidebarMenuItemByHref(string $href): void
332
    {
333
        try {
334
            $xpath       = '//div[@id="sidebar-menu"]//ancestor::a[contains(@class, "item") and contains(@href ,"' . $href . '")]';
335
            $sidebarItem = self::$driver->findElement(WebDriverBy::xpath($xpath));
336
            $actions = new WebDriverActions(self::$driver);
337
            $actions->moveToElement($sidebarItem);
338
            $actions->perform();
339
            $sidebarItem->click();
340
            $this->waitForAjax();
341
        } catch (NoSuchElementException $e) {
342
            $this->fail('Not found sidebar item with href=' . $href . ' on this page' . PHP_EOL);
343
        } catch (Exception $e) {
344
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
345
        }
346
    }
347
348
    /**
349
     * Find modify button on row with text $text and click it
350
     *
351
     * @param string $text
352
     */
353
    protected function clickModifyButtonOnRowWithText(string $text): void
354
    {
355
        $xpath = ('//td[contains(text(),"' . $text . '")]/parent::tr[contains(@class, "row")]//a[contains(@href,"modify")]');
356
        try {
357
            $tableButtonModify = self::$driver->findElement(WebDriverBy::xpath($xpath));
358
            $actions = new WebDriverActions(self::$driver);
359
            $actions->moveToElement($tableButtonModify);
360
            $actions->perform();
361
            $tableButtonModify->click();
362
            $this->waitForAjax();
363
        } catch (NoSuchElementException $e) {
364
            $this->fail('Not found row with text=' . $text . ' on this page' . PHP_EOL);
365
        } catch (Exception $e) {
366
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
367
        }
368
    }
369
370
    /**
371
     * Find modify button on row with id $text and click it
372
     *
373
     * @param string $id
374
     */
375
    protected function clickModifyButtonOnRowWithID(string $id): void
376
    {
377
        $xpath = ('//tr[contains(@class, "row") and @id="' . $id . '"]//a[contains(@href,"modify")]');
378
        try {
379
            $tableButtonModify = self::$driver->findElement(WebDriverBy::xpath($xpath));
380
            $actions = new WebDriverActions(self::$driver);
381
            $actions->moveToElement($tableButtonModify);
382
            $actions->perform();
383
            $tableButtonModify->click();
384
            $this->waitForAjax();
385
        } catch (NoSuchElementException $e) {
386
            $this->fail('Not found row with id=' . $id . ' on this page' . PHP_EOL);
387
        } catch (Exception $e) {
388
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
389
        }
390
    }
391
392
    /**
393
     * Find modify button on row with text $text and click it
394
     *
395
     * @param string $text
396
     */
397
    protected function clickDeleteButtonOnRowWithText(string $text): void
398
    {
399
        $xpath = ('//td[contains(text(),"' . $text . '")]/ancestor::tr[contains(@class, "row")]//a[contains(@href,"delete")]');
400
        try {
401
            $deleteButtons = self::$driver->findElements(WebDriverBy::xpath($xpath));
402
            foreach ($deleteButtons as $deleteButton){
403
                $deleteButton->click();
404
                sleep(2);
405
                $deleteButton->click();
406
            }
407
            $this->waitForAjax();
408
        } catch (NoSuchElementException $e) {
409
            echo('Not found row with text=' . $text . ' on this page in clickDeleteButtonOnRowWithText'. PHP_EOL);
410
        } catch (Exception $e) {
411
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
412
        }
413
    }
414
415
    /**
416
     * Click on add new button by href
417
     *
418
     * @param string $href
419
     */
420
    protected function clickButtonByHref(string $href): void
421
    {
422
        try {
423
            $xpath         = "//a[@href = '{$href}']";
424
            $button_AddNew = self::$driver->findElement(WebDriverBy::xpath($xpath));
425
            $actions = new WebDriverActions(self::$driver);
426
            $actions->moveToElement($button_AddNew);
427
            $actions->perform();
428
            $button_AddNew->click();
429
            $this->waitForAjax();
430
        } catch (NoSuchElementException $e) {
431
            $this->fail('Not found button with href=' . $href . ' on this page on clickButtonByHref' . PHP_EOL);
432
        } catch (Exception $e) {
433
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
434
        }
435
    }
436
437
    /**
438
     * Select tab in tabular menu by anchor
439
     *
440
     * @param $anchor
441
     */
442
    protected function changeTabOnCurrentPage($anchor): void
443
    {
444
        try {
445
            $xpath = "//div[contains(@class, 'tabular') and contains(@class, 'menu')]//a[contains(@data-tab,'{$anchor}')]";
446
            $tab   = self::$driver->findElement(WebDriverBy::xpath($xpath));
447
            $actions = new WebDriverActions(self::$driver);
448
            $actions->moveToElement($tab);
449
            $actions->perform();
450
            $tab->click();
451
        } catch (NoSuchElementException $e) {
452
            $this->fail('Not found tab with anchor=' . $anchor . ' on this page in changeTabOnCurrentPage' . PHP_EOL);
453
        } catch (Exception $e) {
454
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
455
        }
456
    }
457
458
    /**
459
     * Open additional settings under accordion element
460
     */
461
    protected function openAccordionOnThePage(): void
462
    {
463
        try {
464
            $xpath = "//div[contains(@class, 'ui') and contains(@class, 'accordion')]";
465
            $accordion   = self::$driver->findElement(WebDriverBy::xpath($xpath));
466
            $actions = new WebDriverActions(self::$driver);
467
            $actions->moveToElement($accordion);
468
            $actions->perform();
469
            $accordion->click();
470
        } catch (NoSuchElementException $e) {
471
            $this->fail('Not found usual accordion element on this page on openAccordionOnThePage' . PHP_EOL);
472
        } catch (Exception $e) {
473
            $this->fail('Unknown error ' . $e->getMessage() .' on openAccordionOnThePage'. PHP_EOL);
474
        }
475
    }
476
477
    /**
478
     * Get ID from hidden input at form
479
     *
480
     * @return string
481
     */
482
    protected function getCurrentRecordID(): string
483
    {
484
        try {
485
            $xpath = '//input[@name="id" and (@type="hidden")]';
486
            $input = self::$driver->findElement(WebDriverBy::xpath($xpath));
487
            return $input->getAttribute('value')??'';
488
        } catch (NoSuchElementException $e) {
489
            $this->fail('Not found input with name ID on this page getCurrentRecordID' . PHP_EOL);
490
        } catch (Exception $e) {
491
            $this->fail('Unknown error ' . $e->getMessage() . PHP_EOL);
492
        }
493
        return '';
494
    }
495
496
    /**
497
     * Delete all records from table
498
     *
499
     * @param string $tableId
500
     *
501
     * @return void
502
     */
503
    protected function deleteAllRecordsOnTable(string $tableId): void
504
    {
505
        $xpath         = "//table[@id='{$tableId}']//a[contains(@href,'delete') and not(contains(@class,'disabled'))]";
506
        $deleteButtons = self::$driver->findElements(WebDriverBy::xpath($xpath));
507
        while (count($deleteButtons) > 0) {
508
            try {
509
                $deleteButton = self::$driver->findElement(WebDriverBy::xpath($xpath));
510
                $deleteButton->click();
511
                sleep(1);
512
                $deleteButton->click();
513
                $this->waitForAjax();
514
                unset($deleteButtons[0]);
515
            } catch (NoSuchElementException $e) {
516
                break;
517
            }
518
        }
519
    }
520
521
522
}
523