1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Novaway\CommonContexts\Context; |
4
|
|
|
|
5
|
|
|
use Behat\Mink\Element\DocumentElement; |
6
|
|
|
|
7
|
|
|
class Select2Context extends BaseContext |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* Fills in Select2 field with specified |
11
|
|
|
* |
12
|
|
|
* @When /^(?:|I )fill in select2 "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/ |
13
|
|
|
* @When /^(?:|I )fill in select2 "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/ |
14
|
|
|
*/ |
15
|
|
|
public function iFillInSelect2Field($field, $value) |
16
|
|
|
{ |
17
|
|
|
$page = $this->getSession()->getPage(); |
18
|
|
|
|
19
|
|
|
$this->openField($page, $field); |
20
|
|
|
$this->selectValue($page, $field, $value); |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Fill Select2 input field |
25
|
|
|
* |
26
|
|
|
* @When /^(?:|I )fill in select2 input "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/ |
27
|
|
|
*/ |
28
|
|
|
public function iFillInSelect2InputWith($field, $value) |
29
|
|
|
{ |
30
|
|
|
$page = $this->getSession()->getPage(); |
31
|
|
|
|
32
|
|
|
$this->openField($page, $field); |
33
|
|
|
$this->fillSearchField($page, $field, $value); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Fill Select2 input field and select a value |
38
|
|
|
* |
39
|
|
|
* @When /^(?:|I )fill in select2 input "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)" and select "(?P<entry>(?:[^"]|\\")*)"$/ |
40
|
|
|
*/ |
41
|
|
|
public function iFillInSelect2InputWithAndSelect($field, $value, $entry) |
42
|
|
|
{ |
43
|
|
|
$page = $this->getSession()->getPage(); |
44
|
|
|
|
45
|
|
|
$this->openField($page, $field); |
46
|
|
|
$this->fillSearchField($page, $field, $value); |
47
|
|
|
$this->selectValue($page, $field, $entry); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Fill Select2 input field |
52
|
|
|
* |
53
|
|
|
* @Then /^(?:|I )should see (?P<num>\d+) choice(?:|s) in select2 "(?P<field>(?:[^"]|\\")*)"$/ |
54
|
|
|
*/ |
55
|
|
|
public function iShouldSeeSelectChoices($field, $num) |
56
|
|
|
{ |
57
|
|
|
$selector = sprintf('#select2-%s-results li', $field); |
58
|
|
|
|
59
|
|
|
$this->assertSession()->elementsCount('css', $selector, intval($num)); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Open Select2 choice list |
64
|
|
|
* |
65
|
|
|
* @param DocumentElement $page |
66
|
|
|
* @param string $field |
67
|
|
|
* @throws \Exception |
68
|
|
|
*/ |
69
|
|
View Code Duplication |
private function openField(DocumentElement $page, $field) |
|
|
|
|
70
|
|
|
{ |
71
|
|
|
$fieldName = sprintf('select[name="%s"] + .select2-container', $field); |
72
|
|
|
|
73
|
|
|
$inputField = $page->find('css', $fieldName); |
74
|
|
|
if (!$inputField) { |
75
|
|
|
throw new \Exception(sprintf('No field "%s" found', $field)); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
$choice = $inputField->find('css', '.select2-selection'); |
79
|
|
|
if (!$choice) { |
80
|
|
|
throw new \Exception(sprintf('No select2 choice found for "%s"', $field)); |
81
|
|
|
} |
82
|
|
|
$choice->press(); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Fill Select2 search field |
87
|
|
|
* |
88
|
|
|
* @param DocumentElement $page |
89
|
|
|
* @param string $field |
90
|
|
|
* @param string $value |
91
|
|
|
* @throws \Exception |
92
|
|
|
*/ |
93
|
|
|
private function fillSearchField(DocumentElement $page, $field, $value) |
94
|
|
|
{ |
95
|
|
|
$driver = $this->getSession()->getDriver(); |
96
|
|
|
if ('Behat\Mink\Driver\Selenium2Driver' === get_class($driver)) { |
97
|
|
|
// Can't use `$this->getSession()->getPage()->find()` because of https://github.com/minkphp/MinkSelenium2Driver/issues/188 |
98
|
|
|
$select2Input = $this->getSession()->getDriver()->getWebDriverSession()->element('xpath', "//html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' select2-search__field ')]"); |
|
|
|
|
99
|
|
|
if (!$select2Input) { |
100
|
|
|
throw new \Exception(sprintf('No field "%s" found', $field)); |
101
|
|
|
} |
102
|
|
|
$select2Input->postValue(['value' => [$value]]); |
103
|
|
|
} else { |
104
|
|
|
$select2Input = $page->find('css', '.select2-search__field'); |
105
|
|
|
if (!$select2Input) { |
106
|
|
|
throw new \Exception(sprintf('No input found for "%s"', $field)); |
107
|
|
|
} |
108
|
|
|
$select2Input->setValue($value); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
$this->waitForLoadingResults(); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Select value in choice list |
116
|
|
|
* |
117
|
|
|
* @param DocumentElement $page |
118
|
|
|
* @param string $field |
119
|
|
|
* @param string $value |
120
|
|
|
* @throws \Exception |
121
|
|
|
*/ |
122
|
|
|
private function selectValue(DocumentElement $page, $field, $value) |
123
|
|
|
{ |
124
|
|
|
$this->waitForLoadingResults(); |
125
|
|
|
|
126
|
|
|
$chosenResults = $page->findAll('css', '.select2-results li'); |
127
|
|
|
foreach ($chosenResults as $result) { |
128
|
|
|
if ($result->getText() == $value) { |
129
|
|
|
$result->click(); |
130
|
|
|
return; |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
throw new \Exception(sprintf('Value "%s" not found for "%s"', $value, $field)); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Wait the end of fetching Select2 results |
139
|
|
|
* |
140
|
|
|
* @param int $time Time to wait in seconds |
141
|
|
|
*/ |
142
|
|
|
private function waitForLoadingResults($time = 60) |
143
|
|
|
{ |
144
|
|
|
for ($i = 0; $i < $time; $i++) { |
145
|
|
|
if (!$this->getSession()->getPage()->find('css', '.select2-results__option.loading-results')) { |
146
|
|
|
return true; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
sleep(1); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
throw new \Exception(sprintf('Results are not load after "%d" seconds.', $time)); |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
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.