• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eliashaeussler / typo3-codeception-helper / 13198500180

07 Feb 2025 11:01AM UTC coverage: 80.556% (+2.9%) from 77.686%
13198500180

push

github

web-flow
Merge pull request #47 from eliashaeussler/feature/scroll-to-element

[FEATURE] Introduce `Backend::scrollToElementInModule()` helper method

24 of 25 new or added lines in 1 file covered. (96.0%)

116 of 144 relevant lines covered (80.56%)

2.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.73
/src/Codeception/Module/Backend.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer package "eliashaeussler/typo3-codeception-helper".
7
 *
8
 * Copyright (C) 2023-2025 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\Typo3CodeceptionHelper\Codeception\Module;
25

26
use Codeception\Module;
27
use EliasHaeussler\Typo3CodeceptionHelper\Enums;
28
use Facebook\WebDriver;
29

30
use function reset;
31
use function sprintf;
32

33
/**
34
 * Backend.
35
 *
36
 * @author Elias Häußler <elias@haeussler.dev>
37
 * @license GPL-2.0-or-later
38
 *
39
 * @method never fail(string $message = '')
40
 */
41
final class Backend extends Module
42
{
43
    /**
44
     * @var array{userCredentials: array<string, string>}
45
     */
46
    protected array $config = [
47
        'userCredentials' => [
48
            'admin' => 'password',
49
        ],
50
    ];
51

52
    /**
53
     * Perform backend login for the given user. The user is identified
54
     * by the given username and is authenticated by the given password.
55
     *
56
     * Example
57
     * =======
58
     *
59
     * $I->login('admin', 'password');
60
     */
61
    public function login(string $username, string $password): void
2✔
62
    {
63
        $I = $this->getWebDriver();
2✔
64

65
        $I->amOnPage('/typo3/');
2✔
66
        $I->waitForElementVisible(Enums\Selectors::BackendLoginUsernameField->value);
2✔
67
        $I->waitForElementVisible(Enums\Selectors::BackendLoginPasswordField->value);
2✔
68
        $I->fillField(Enums\Selectors::BackendLoginUsernameField->value, $username);
2✔
69
        $I->fillField(Enums\Selectors::BackendLoginPasswordField->value, $password);
2✔
70
        $I->click(Enums\Selectors::BackendLoginSubmitButton->value);
2✔
71
        $I->waitForElementNotVisible(Enums\Selectors::BackendLoginForm->value);
2✔
72
        $I->seeCookie('be_typo_user');
2✔
73
    }
74

75
    /**
76
     * Perform backend login for the given user. The user is identified
77
     * by the given username which must be configured in the codeception
78
     * module config.
79
     *
80
     * Example
81
     * =======
82
     *
83
     * $I->loginAs('admin');
84
     *
85
     * @param non-empty-string $username
86
     */
87
    public function loginAs(string $username): void
2✔
88
    {
89
        if (!is_string($this->config['userCredentials'][$username] ?? null)) {
2✔
90
            $this->fail(
1✔
91
                sprintf('A user with username "%s" is not configured.', $username),
1✔
92
            );
1✔
93
        }
94

95
        $this->login($username, $this->config['userCredentials'][$username]);
1✔
96
    }
97

98
    /**
99
     * Open a backend module by clicking on the module link. The module
100
     * link is identified by a given node identifier. Note that the
101
     * identifier differs between TYPO3 versions (see example below).
102
     *
103
     * Example
104
     * =======
105
     *
106
     * TYPO3 11
107
     * --------
108
     * $I->openModule('#web_list');
109
     *
110
     * TYPO3 12
111
     * --------
112
     * $I->openModule('[data-modulemenu-identifier="web_list"]');
113
     */
114
    public function openModule(string $identifier): void
1✔
115
    {
116
        $I = $this->getWebDriver();
1✔
117

118
        $I->waitForElementClickable($identifier, 5);
1✔
119
        $I->click($identifier);
1✔
120
        $I->switchToIFrame(Enums\Selectors::BackendContentFrame->value);
1✔
121
    }
122

123
    public function scrollToElementInModule(string $identifier, int $offsetX = 0, int $offsetY = 0): void
3✔
124
    {
125
        $I = $this->getWebDriver();
3✔
126

127
        /** @var WebDriver\Remote\RemoteWebElement[] $elements */
128
        $elements = $I->_findElements($identifier);
3✔
129
        $element = reset($elements);
3✔
130

131
        if (false === $element) {
3✔
132
            $this->fail(
1✔
133
                sprintf('Element "%s" not found.', $identifier),
1✔
134
            );
1✔
135
        }
136

137
        // Make sure we're in content frame
138
        $I->switchToFrame();
2✔
139
        $I->switchToFrame(Enums\Selectors::BackendContentFrame->value);
2✔
140

141
        $moduleSelector = Enums\Selectors::BackendModuleWrapper->value;
2✔
142
        $x = $element->getLocation()->getX() + $offsetX;
2✔
143
        $y = $element->getLocation()->getY() + $offsetY;
2✔
144

145
        $I->executeJS(<<<JS
2✔
146
document.querySelector('{$moduleSelector}').scrollLeft = {$x};
2✔
147
document.querySelector('{$moduleSelector}').scrollTop = {$y};
2✔
148
JS
2✔
149
        );
2✔
150
    }
151

152
    private function getWebDriver(): Module\WebDriver
6✔
153
    {
154
        if (!$this->hasModule('WebDriver')) {
6✔
NEW
155
            $this->fail('WebDriver module is not enabled.');
×
156
        }
157

158
        /** @var Module\WebDriver $webDriver */
159
        $webDriver = $this->getModule('WebDriver');
6✔
160

161
        return $webDriver;
6✔
162
    }
163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc