Completed
Pull Request — master (#347)
by Łukasz
17:04
created

ListElement   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 3
dl 0
loc 185
rs 9.84
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A getColumns() 0 4 1
A getNamedColumn() 0 5 1
A hasBatchColumn() 0 4 1
A getRows() 0 4 1
A getRowsIds() 0 9 2
A getRow() 0 9 2
A getRowId() 0 4 1
A getNamedRowId() 0 4 1
A getNamedRow() 0 6 1
A getRowsCount() 0 4 1
A getCell() 0 5 1
A getColumnPosition() 0 15 4
A isColumnEditable() 0 4 1
A isColumnSortable() 0 6 2
A isColumnAscSortActive() 0 6 1
A isColumnDescSortActive() 0 6 1
A pressSortButton() 0 13 3
A clickRowAction() 0 4 1
A getColumnHeader() 0 4 1
A getTable() 0 9 2
A getNotEmptyTexts() 0 12 3
1
<?php
2
3
/**
4
 * (c) FSi sp. z o.o. <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace FSi\Bundle\AdminBundle\Behat\Element;
13
14
use Behat\Mink\Element\NodeElement;
15
use SensioLabs\Behat\PageObjectExtension\PageObject\Element;
16
use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\UnexpectedPageException;
17
18
class ListElement extends Element
19
{
20
    public const BATCH_COLUMN = 'batch';
21
22
    protected $selector = ['css' => 'body'];
23
24
    /**
25
     * @return NodeElement[]
26
     */
27
    public function getColumns(): array
28
    {
29
        return $this->getNotEmptyTexts($this->getTable()->findAll('css', 'th'));
30
    }
31
32
    /**
33
     * @param string $name
34
     * @return NodeElement|null
35
     */
36
    public function getNamedColumn(string $name): ?NodeElement
37
    {
38
        $selector = '//th[normalize-space(text())="%s"]/ancestor::tr';
39
        return $this->getTable()->find('xpath', sprintf($selector, $name));
40
    }
41
42
    public function hasBatchColumn(): bool
43
    {
44
        return $this->has('css', 'th > input[type="checkbox"]');
45
    }
46
47
    /**
48
     * @return NodeElement[]
49
     */
50
    public function getRows(): array
51
    {
52
        return $this->getTable()->findAll('css', 'tbody > tr');
53
    }
54
55
    /**
56
     * @return string[]
57
     */
58
    public function getRowsIds(): array
59
    {
60
        $ids = [];
61
        foreach ($this->getRows() as $row) {
62
            $ids[] = $row->find('css', 'input[type=checkbox]')->getAttribute('value');
63
        }
64
65
        return $ids;
66
    }
67
68
    public function getRow(int $number): NodeElement
69
    {
70
        $row = $this->find('xpath', sprintf('//tbody/tr[%d]', $number));
71
        if (!isset($row)) {
72
            throw new UnexpectedPageException(sprintf('Row "%s" does not exist in DataGrid', $number));
73
        }
74
75
        return $row;
76
    }
77
78
    public function getRowId(int $number): string
79
    {
80
        return $this->getRow($number)->find('css', 'input[type=checkbox]')->getAttribute('value');
81
    }
82
83
    public function getNamedRowId(string $name): string
84
    {
85
        return $this->getNamedRow($name)->find('css', 'input[type=checkbox]')->getAttribute('value');
86
    }
87
88
    /**
89
     * @param string $name
90
     * @return NodeElement
91
     */
92
    public function getNamedRow(string $name): NodeElement
93
    {
94
        $selector = '//span[@class="datagrid-cell-value" and normalize-space(text())="%s"]/ancestor::tr';
95
96
        return $this->getTable()->find('xpath', sprintf($selector, $name));
97
    }
98
99
    public function getRowsCount(): int
100
    {
101
        return count($this->getRows());
102
    }
103
104
    public function getCell($columnHeader, $rowNumber): ?NodeElement
105
    {
106
        $columnPos = $this->getColumnPosition($columnHeader);
107
        return $this->find('xpath', sprintf('descendant-or-self::table/tbody/tr[%d]/td[%d]', $rowNumber, $columnPos));
108
    }
109
110
    public function getColumnPosition(string $columnHeader): int
111
    {
112
        $headers = $this->findAll('css', 'th');
113
        foreach ($headers as $index => $header) {
114
            /** @var NodeElement $header */
115
            if (
116
                $header->has('css', 'span')
117
                && $header->find('css', 'span')->getText() === $columnHeader
118
            ) {
119
                return $index + 1;
120
            }
121
        }
122
123
        throw new UnexpectedPageException(sprintf('Can\'t find column %s', $columnHeader));
124
    }
125
126
    public function isColumnEditable(string $columnHeader): bool
127
    {
128
        return $this->getCell($columnHeader, 1)->has('css', 'a.editable');
129
    }
130
131
    public function isColumnSortable(string $columnHeader): bool
132
    {
133
        $column = $this->getColumnHeader($columnHeader);
134
135
        return $column->has('css', '.sort-asc') && $column->has('css', '.sort-desc');
136
    }
137
138
    public function isColumnAscSortActive(string $columnHeader): bool
139
    {
140
        $sortButton = $this->getColumnHeader($columnHeader)->find('css', '.sort-asc');
141
142
        return !$sortButton->hasAttribute('disabled');
143
    }
144
145
    public function isColumnDescSortActive(string $columnHeader): bool
146
    {
147
        $sortButton = $this->getColumnHeader($columnHeader)->find('css', '.sort-desc');
148
149
        return !$sortButton->hasAttribute('disabled');
150
    }
151
152
    public function pressSortButton(string $columnHeader, string $sort): void
153
    {
154
        switch (strtolower($sort)) {
155
            case 'sort asc':
156
                $this->getColumnHeader($columnHeader)->find('css', '.sort-asc')->click();
157
                break;
158
            case 'sort desc':
159
                $this->getColumnHeader($columnHeader)->find('css', '.sort-desc')->click();
160
                break;
161
            default:
162
                throw new UnexpectedPageException(sprintf("Unknown sorting type %s", $sort));
163
        }
164
    }
165
166
    public function clickRowAction(int $rowNumber, string $action): void
167
    {
168
        $this->getCell('Actions', $rowNumber)->clickLink($action);
169
    }
170
171
    private function getColumnHeader(string $columnHeader): ?NodeElement
172
    {
173
        return $this->find('css', sprintf('th span:contains("%s")', $columnHeader))->getParent();
174
    }
175
176
    private function getTable(): NodeElement
177
    {
178
        $table = $this->find('css', 'table.table-datagrid');
179
        if (null === $table) {
180
            throw new UnexpectedPageException('There is no datagrid table on page');
181
        }
182
183
        return $table;
184
    }
185
186
    /**
187
     * @param NodeElement[] $elements
188
     * @return string[]
189
     */
190
    private function getNotEmptyTexts(array $elements): array
191
    {
192
        $texts = [];
193
        /** @var Element $column */
194
        foreach ($elements as $column) {
195
            $text = $column->getText();
196
            if (!empty($text)) {
197
                $texts[] = $text;
198
            }
199
        }
200
        return $texts;
201
    }
202
}
203