InaccurateText::__toString()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 0
cts 7
cp 0
rs 9.4285
cc 3
eloc 6
nc 2
nop 0
crap 12
1
<?php
2
/**
3
 * @author Sergii Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Utils\XPath;
6
7
// Helpers.
8
use Behat\DebugExtension\Debugger;
9
use Behat\Mink\Element\NodeElement;
10
11
class InaccurateText
12
{
13
    use Debugger;
14
15
    /**
16
     * The text, desired to be found.
17
     *
18
     * @var string
19
     */
20
    private $text = '';
21
    /**
22
     * XPath query.
23
     *
24
     * @var string
25
     */
26
    private $query = '';
27
    /**
28
     * The name of element's attribute (without "@" symbol). If will
29
     * be specified then inaccurate search will be done in its value.
30
     *
31
     * @var string
32
     */
33
    private $attribute = '';
34
    /**
35
     * An element to search in. Must be specified to performing queries.
36
     *
37
     * @var NodeElement
38
     */
39
    private $parent;
40
41
    /**
42
     * @code
43
     * // Any labels with text.
44
     * // XPath: //label[text()]
45
     * (string) (new InaccurateText)->query('//label');
46
     * @endcode
47
     *
48
     * @code
49
     * // Any labels with "for" attribute and text().
50
     * // XPath: //label[@for][text()]
51
     * (string) (new InaccurateText)->query('//label[@for]'),
52
     * @endcode
53
     *
54
     * @code
55
     * // Any labels with text, starts with "The text".
56
     * // XPath: //label[text()[starts-with(., 'The text')]]
57
     * (string) (new InaccurateText)->query('//label')->text('The text');
58
     * @endcode
59
     *
60
     * @code
61
     * // Any labels with text in "data-title" attribute starts with "The text".
62
     * // XPath: //label[@data-title[starts-with(., 'The text')]]
63
     * (string) (new InaccurateText)->query('//label')->attribute('data-title')->text('The text');
64
     * @endcode
65
     *
66
     * @code
67
     * // Any parent elements with text in "method" attribute starts with "POST".
68
     * // XPath: /ancestor::*[@method[starts-with(., 'POST')]]
69
     * (new InaccurateText)->query('/ancestor::*')->attribute('method')->text('POST');
70
     * @endcode
71
     *
72
     * @param string $query
73
     * @param NodeElement $parent
74
     */
75
    public function __construct($query, NodeElement $parent = null)
76
    {
77
        if (empty($query)) {
78
            throw new \InvalidArgumentException('You need to initialize XPath query.');
79
        }
80
81
        $this->query = $query;
82
        $this->parent = $parent;
83
    }
84
85
    /**
86
     * @return string
87
     *   XPath selector.
88
     */
89
    public function __toString()
90
    {
91
        if (!empty($this->text)) {
92
            $this->text = "[starts-with(normalize-space(.), '$this->text')]";
93
        }
94
95
        $xpath = sprintf("$this->query[%s$this->text]", empty($this->attribute) ? 'text()' : "@$this->attribute");
96
97
        self::debug(['XPath: %s'], [$xpath]);
98
99
        return $xpath;
100
    }
101
102
    /**
103
     * @param string $text
104
     *
105
     * @return $this
106
     */
107
    public function text($text)
108
    {
109
        $this->text = $text;
110
111
        return $this;
112
    }
113
114
    /**
115
     * @param string $attribute
116
     *
117
     * @return $this
118
     */
119
    public function attribute($attribute)
120
    {
121
        $this->attribute = $attribute;
122
123
        return $this;
124
    }
125
126
    /**
127
     * @return NodeElement[]
128
     */
129
    public function findAll()
130
    {
131
        if (null === $this->parent) {
132
            throw new \RuntimeException(sprintf('An object "%s" instantiated incorrectly.', __CLASS__));
133
        }
134
135
        return $this->parent->findAll('xpath', (string) $this);
136
    }
137
138
    /**
139
     * @return NodeElement
140
     */
141
    public function find()
142
    {
143
        $items = $this->findAll();
144
145
        return empty($items) ? null : current($items);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression empty($items) ? null : current($items); of type Behat\Mink\Element\NodeElement|false adds false to the return on line 145 which is incompatible with the return type documented by Drupal\TqExtension\Utils...th\InaccurateText::find of type Behat\Mink\Element\NodeElement. It seems like you forgot to handle an error condition.
Loading history...
146
    }
147
}
148