Completed
Pull Request — 3.1 (#348)
by Piotr
07:35
created

ListElement   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 3
dl 0
loc 184
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 14 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
    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 ($header->has('css', 'span')
116
                && $header->find('css', 'span')->getText() === $columnHeader
117
            ) {
118
                return $index + 1;
119
            }
120
        }
121
122
        throw new UnexpectedPageException(sprintf('Can\'t find column %s', $columnHeader));
123
    }
124
125
    public function isColumnEditable(string $columnHeader): bool
126
    {
127
        return $this->getCell($columnHeader, 1)->has('css', 'a.editable');
128
    }
129
130
    public function isColumnSortable(string $columnHeader): bool
131
    {
132
        $column = $this->getColumnHeader($columnHeader);
133
134
        return $column->has('css', '.sort-asc') && $column->has('css', '.sort-desc');
135
    }
136
137
    public function isColumnAscSortActive(string $columnHeader): bool
138
    {
139
        $sortButton = $this->getColumnHeader($columnHeader)->find('css', '.sort-asc');
140
141
        return !$sortButton->hasAttribute('disabled');
142
    }
143
144
    public function isColumnDescSortActive(string $columnHeader): bool
145
    {
146
        $sortButton = $this->getColumnHeader($columnHeader)->find('css', '.sort-desc');
147
148
        return !$sortButton->hasAttribute('disabled');
149
    }
150
151
    public function pressSortButton(string $columnHeader, string $sort): void
152
    {
153
        switch (strtolower($sort)) {
154
            case 'sort asc':
155
                $this->getColumnHeader($columnHeader)->find('css', '.sort-asc')->click();
156
                break;
157
            case 'sort desc':
158
                $this->getColumnHeader($columnHeader)->find('css', '.sort-desc')->click();
159
                break;
160
            default:
161
                throw new UnexpectedPageException(sprintf("Unknown sorting type %s", $sort));
162
        }
163
    }
164
165
    public function clickRowAction(int $rowNumber, string $action): void
166
    {
167
        $this->getCell('Actions', $rowNumber)->clickLink($action);
168
    }
169
170
    private function getColumnHeader(string $columnHeader): ?NodeElement
171
    {
172
        return $this->find('css', sprintf('th span:contains("%s")', $columnHeader))->getParent();
173
    }
174
175
    private function getTable(): NodeElement
176
    {
177
        $table = $this->find('css', 'table.table-datagrid');
178
        if (null === $table) {
179
            throw new UnexpectedPageException('There is no datagrid table on page');
180
        }
181
182
        return $table;
183
    }
184
185
    /**
186
     * @param NodeElement[] $elements
187
     * @return string[]
188
     */
189
    private function getNotEmptyTexts(array $elements): array
190
    {
191
        $texts = [];
192
        /** @var Element $column */
193
        foreach ($elements as $column) {
194
            $text = $column->getText();
195
            if (!empty($text)) {
196
                $texts[] = $text;
197
            }
198
        }
199
        return $texts;
200
    }
201
}
202