-
Notifications
You must be signed in to change notification settings - Fork 638
/
PageTree.php
152 lines (130 loc) · 5.47 KB
/
PageTree.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Tests\Acceptance\Support\Helper;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\RemoteWebElement;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverKeys;
use TYPO3\CMS\Core\Tests\Acceptance\Support\ApplicationTester;
use TYPO3\TestingFramework\Core\Acceptance\Helper\AbstractPageTree;
final class PageTree extends AbstractPageTree
{
private Mouse $mouse;
/**
* Inject our core AcceptanceTester actor into PageTree
*/
public function __construct(ApplicationTester $I, Mouse $mouse)
{
$this->tester = $I;
$this->mouse = $mouse;
}
/**
* Waits until tree nodes are rendered
*/
public function waitForNodes(): void
{
$this->tester->waitForElement(static::$pageTreeSelector . ' ' . static::$treeItemSelector, 5);
}
/**
* Open the given hierarchical path in the pagetree and click the last page.
*
* Example to open "styleguide -> elements basic" page:
* [
* 'styleguide TCA demo',
* 'elements basic',
* ]
*
* @param string[] $path
*/
public function openPath(array $path)
{
$context = $this->getPageTreeElement();
$this->waitForNodes();
// Collapse all opened paths (might be opened due to localstorage)
do {
$toggled = false;
try {
// collapse last opened node element, that is not the root (=first node)
$context->findElement(\Facebook\WebDriver\WebDriverBy::xpath('(.//*[position()>1 and @role="treeitem" and */@class="node-toggle node-toggle--expanded chevron expanded"])[last()]/*[starts-with(@class, "node-toggle")]'))->click();
$toggled = true;
} catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) {
// element not found so it may be already opened...
} catch (\Facebook\WebDriver\Exception\ElementNotVisibleException $e) {
// element not found so it may be already opened...
} catch (\Facebook\WebDriver\Exception\ElementNotInteractableException $e) {
// another possible exception if the chevron isn't there ... depends on facebook driver version
}
} while ($toggled);
parent::openPath($path);
// pagetree has 300ms timeout for double click detection, wait 350ms to wait for the click to have happened
$this->tester->wait(0.35);
}
/**
* Search for an element with the given link text in the provided context.
*
* @param string $nodeText
* @param RemoteWebElement $context
* @return RemoteWebElement
*/
protected function ensureTreeNodeIsOpen(string $nodeText, RemoteWebElement $context)
{
$I = $this->tester;
$I->see($nodeText, self::$treeItemSelector);
/** @var RemoteWebElement $context */
$context = $I->executeInSelenium(function () use (
$nodeText,
$context
) {
return $context->findElement(\Facebook\WebDriver\WebDriverBy::xpath('//*[text()=\'' . $nodeText . '\']/..'));
});
try {
$context->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('.chevron.collapsed[visibility="visible"]'))->click();
} catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) {
// element not found so it may be already opened...
} catch (\Facebook\WebDriver\Exception\ElementNotVisibleException $e) {
// element not found so it may be already opened...
} catch (\Facebook\WebDriver\Exception\ElementNotInteractableException $e) {
// another possible exception if the chevron isn't there ... depends on facebook driver version
}
return $context;
}
/**
* Perform drag and drop for a new page into the given target page.
*/
public function dragAndDropNewPage(string $pageName, string $dragNode, string $nodeEditInput): void
{
$target = $this->getPageXPathByPageName($pageName);
$pageTitle = sprintf('Dummy 1-%s-new', $pageName);
$this->mouse->dragAndDrop($dragNode, $target);
$this->tester->seeElement($nodeEditInput);
// Change the new page title.
// We can't use $I->fillField() here since this sends a clear() to the element
// which drops the node creation in the tree. So we do it manually with selenium.
$element = $this->tester->executeInSelenium(static function (RemoteWebDriver $webdriver) use ($nodeEditInput) {
return $webdriver->findElement(WebDriverBy::cssSelector($nodeEditInput));
});
$element->sendKeys($pageTitle);
$this->tester->pressKey($nodeEditInput, WebDriverKeys::ENTER);
$this->tester->waitForElementNotVisible($nodeEditInput);
$this->tester->waitForText($pageTitle);
}
/**
* Get node identifier of given page.
*/
public function getPageXPathByPageName(string $pageName): string
{
return '//*[text()=\'' . $pageName . '\']';
}
}