LinkSequence::navigateTo()   C
last analyzed

Complexity

Conditions 8
Paths 16

Size

Total Lines 47
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 47
c 1
b 0
f 0
rs 5.7377
cc 8
eloc 30
nc 16
nop 2
1
<?php
2
3
namespace Magium\Navigators;
4
5
use Facebook\WebDriver\WebDriverBy;
6
use Facebook\WebDriver\WebDriverElement;
7
use Magium\AbstractTestCase;
8
use Magium\InvalidInstructionException;
9
use Magium\Util\Log\LoggerInterface;
10
use Magium\Util\Translator\Translator;
11
use Magium\WebDriver\WebDriver;
12
13
class LinkSequence implements NavigatorInterface
14
{
15
    const NAVIGATOR = 'LinkSequence';
16
17
    protected $webDriver;
18
    protected $testCase;
19
    protected $translator;
20
    protected $path;
21
    protected $logger;
22
23
    /**
24
     * LinkSequence constructor.
25
     * @param AbstractTestCase $testCase
26
     * @param WebDriver $webDriver
27
     */
28
    public function __construct(
29
        AbstractTestCase $testCase,
30
        WebDriver $webDriver,
31
        Translator $translator,
32
        LoggerInterface $logger
33
    )
34
    {
35
        $this->testCase = $testCase;
36
        $this->webDriver = $webDriver;
37
        $this->translator = $translator;
38
        $this->logger = $logger;
39
    }
40
41
    public function navigateTo($path, $clickToSelect = false)
42
    {
43
        // Split on "/" but allow "/" in names by escaping it with "\"
44
        $parts = preg_split('|(?<!\\\)/|', $path);
45
        array_walk(
46
            $parts,
47
            function(&$item) {
48
                $item = str_replace('\\/', '/', $item);
49
            }
50
        );
51
        if (count($parts) == 0) {
52
            throw new InvalidInstructionException('The path must have at least one link to click on');
53
        }
54
        $element = null;
55
        foreach ($parts as $part) {
56
            $this->testCase->sleep('250ms');
57
            $part = $this->translator->translatePlaceholders($part);
58
            $xpath = sprintf('//a[concat(" ",normalize-space(.)," ") = " %s "]|//*[concat(" ",normalize-space(.)," ") = " %s "]/ancestor::a', $part, $part);
59
            $elements = $this->webDriver->findElements(WebDriverBy::xpath($xpath));
60
            $action = false;
61
            $this->testCase->assertNotCount(0, $elements, 'Did not find 1 or more elements with the Xpath: ' . $xpath);
62
            foreach ($elements as $element) {
63
                // Sometimes responsive templates have multiple nav menus.  So we iterate over the results to find a visible element.
64
                if (!$element->isDisplayed()) {
65
                    continue;
66
                }
67
                if ($clickToSelect) {
68
                    $element->click();
69
                } else {
70
                    $this->webDriver->getMouse()->mouseMove($element->getCoordinates());
71
                }
72
                $action = true;
73
                break; // If either of these options work we don't need to iterate over the remain elements
74
            }
75
            $this->testCase->assertTrue($action, 'No action was taken.  Elements not visible?  Xpath: ' . $xpath);
76
        }
77
78
        // We will have already clicked it previously
79
        if (!$clickToSelect) {
80
            if (!$element instanceof WebDriverElement) {
81
                throw new InvalidInstructionException('The element is not an instanceof WebDriverElement.  If you get this exception something weird has happened.');
82
            }
83
            $element->click();
84
        }
85
86
87
    }
88
89
}
90