stepIPressTheButtonInTheAddBlockPopover()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 10
rs 10
1
<?php
2
namespace DNADesign\Elemental\Tests\Behat\Context;
3
4
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
5
use Behat\Mink\Element\NodeElement;
6
use PHPUnit\Framework\Assert;
7
use SilverStripe\BehatExtension\Context\BasicContext;
8
use SilverStripe\BehatExtension\Context\SilverStripeContext;
9
use SilverStripe\Framework\Tests\Behaviour\CmsFormsContext;
10
11
if (!class_exists(SilverStripeContext::class)) {
12
    return;
13
}
14
15
class FeatureContext extends SilverStripeContext
16
{
17
    /**
18
     * @var CmsFormsContext
19
     */
20
    protected $cmsContext;
21
22
    /**
23
     * @var BasicContext
24
     */
25
    protected $basicContext;
26
27
28
    /** @BeforeScenario */
29
    public function gatherContexts(BeforeScenarioScope $scope)
30
    {
31
        $this->cmsContext = $scope->getEnvironment()->getContext(CmsFormsContext::class);
0 ignored issues
show
Bug introduced by
The method getContext() does not exist on Behat\Testwork\Environment\Environment. It seems like you code against a sub-type of Behat\Testwork\Environment\Environment such as Behat\Behat\Context\Envi...lizedContextEnvironment or Behat\Behat\Context\Envi...lizedContextEnvironment. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

31
        $this->cmsContext = $scope->getEnvironment()->/** @scrutinizer ignore-call */ getContext(CmsFormsContext::class);
Loading history...
32
        $this->basicContext = $scope->getEnvironment()->getContext(BasicContext::class);
33
    }
34
35
    /**
36
     * @Then /^I should( not |\s+)see the edit form for block (\d+)$/i
37
     */
38
    public function iShouldSeeTheEditFormForBlock($negative, $position)
39
    {
40
        $iShouldNotSee = $negative === ' not ';
41
42
        $block = $this->getSpecificBlock($position);
43
44
        $form = $block->find('css', '.element-editor-editform');
45
46
        if ($iShouldNotSee) {
47
            Assert::assertTrue(!$form || !$form->isVisible(), 'I see the form! Try again later.');
48
        } else {
49
            Assert::assertNotNull($form, 'Edit form not found');
50
            Assert::assertTrue($form->isVisible());
51
        }
52
    }
53
54
    /**
55
     * @Then /^I (?:should\s)?see a list of blocks$/i
56
     */
57
    public function iShouldSeeAListOfBlocks()
58
    {
59
        Assert::assertNotEmpty($this->getBlocks());
60
    }
61
62
    /**
63
     * @Then /^I (?:should\s)?see an empty list of blocks$/i
64
     */
65
    public function iShouldSeeAnEmptyListOfBlocks()
66
    {
67
        Assert::assertEmpty($this->getBlocks());
68
    }
69
70
    /**
71
     * @Then I should see block :position
72
     */
73
    public function iShouldSeeBlock($position)
74
    {
75
        Assert::assertNotNull($this->getSpecificBlock($position));
76
    }
77
78
    /**
79
     * @When /^I click on block (\d+)(?:\sagain)?$/i
80
     */
81
    public function iClickOnBlock($position)
82
    {
83
        $block = $this->getSpecificBlock($position);
84
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
85
        $block->click();
86
    }
87
88
    /**
89
     * @When /^I click on the caret button for block (\d+)(?:\sagain)?$/i
90
     */
91
    public function iClickOnTheCaretButtonForBlock($position)
92
    {
93
        $block = $this->getSpecificBlock($position);
94
        $button = $this->getCaretButton($block);
95
        Assert::assertNotNull($button, 'Caret button for block ' . $position . ' was not found in the page.');
96
        $button->click();
97
    }
98
99
    /**
100
     * @Then I should see :text as the title for block :position
101
     */
102
    public function iShouldSeeAsTheTitleForBlock($text, $position)
103
    {
104
        $block = $this->getSpecificBlock($position);
105
        $title = $block->find('css', '.element-editor-header__title');
106
        Assert::assertEquals($title->getText(), $text);
107
    }
108
109
    /**
110
     * @Then I should see :text as the summary for block :position
111
     */
112
    public function iShouldSeeAsTheSummaryForBlock($text, $position)
113
    {
114
        $block = $this->getSpecificBlock($position);
115
        $summary = $block->find('css', '.element-editor-summary__content');
116
        Assert::assertEquals($summary->getText(), $text);
117
    }
118
119
    /**
120
     * @Then I should see the archive button for block :position
121
     *
122
     * @param int $position
123
     */
124
    public function iShouldSeeArchiveButtonForBlock($position)
125
    {
126
        $this->getArchiveButton($position);
127
    }
128
129
    /**
130
     * @Then /^I should( not |\s+)see the publish button for block (\d+)$/i
131
     *
132
     * @param string $negative
133
     * @param int $position
134
     *
135
     */
136
    public function iShouldSeeThePublishButtonForBlock($negative, $position)
137
    {
138
        $iShouldNotSee = $negative === ' not ';
139
140
        $publishButton = $this->findPublishButton($position);
141
142
        if ($iShouldNotSee) {
143
            Assert::assertNull($publishButton, 'Publish button displayed (but shouldn\'t)');
144
        } else {
145
            Assert::assertNotNull($publishButton, 'Publish button not displayed (but should be)');
146
        }
147
    }
148
149
    /**
150
     * @Then /^I should( not |\s+)see the unpublish button for block (\d+)$/i
151
     *
152
     * @param string $negative
153
     * @param int $position
154
     */
155
    public function iShouldSeeTheUnpublishButtonForBlock($negative, $position)
156
    {
157
        $iShouldNotSee = $negative === ' not ';
158
159
        $unpublishButton = $this->findUnpublishButton($position);
160
161
        if ($iShouldNotSee) {
162
            Assert::assertNull($unpublishButton, 'Unpublish button displayed (but shouldn\'t)');
163
        } else {
164
            Assert::assertNotNull($unpublishButton, 'Unpublish button not displayed (but should be)');
165
        }
166
    }
167
168
    /**
169
     * @When I hover over block :position
170
     *
171
     * @param int $position
172
     */
173
    public function iHoverOverBlock($position)
174
    {
175
        $block = $this->getSpecificBlock($position);
176
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
177
        $block->mouseOver();
178
    }
179
180
    /**
181
     * @When I hover over the icon of block :position
182
     *
183
     * @param int $position
184
     */
185
    public function iHoverOverTheIconOfBlock($position)
186
    {
187
        $block = $this->getSpecificBlock($position);
188
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
189
        $icon = $block->find(
190
            'css',
191
            '.element-editor-header .element-editor-header__info .element-editor-header__icon-container'
192
        );
193
        $icon->mouseOver();
194
    }
195
196
    /**
197
     * @Given /^I press the "([^"]*)" button in the add block popover$/
198
     * @param string $text
199
     */
200
    public function stepIPressTheButtonInTheAddBlockPopover($text)
201
    {
202
        $popover = $this->getSession()->getPage()->find('css', '.popover-option-set');
203
204
        $blockType = strtolower($text ?? '');
205
206
        // Selector preferable not font-icon, but other class shared among all buttons
207
        $button = $popover->find('css', '.font-icon-block-'. $blockType);
208
        Assert::assertNotNull($button, "{$text} button not found in Add Block popover");
209
        $button->click();
210
    }
211
212
    /**
213
     * @Given /^I press the "([^"]*)" button in the actions? menu for block (\d+)$/
214
     */
215
    public function stepIPressTheButtonInTheActionMenuForBlock($buttonName, $blockNumber)
216
    {
217
        $block = $this->getSpecificBlock($blockNumber);
218
219
        // Check if the popover is open for the block
220
        $popover = $block->find('css', '.action-menu__dropdown');
221
        if (!$popover->isVisible()) {
222
            $block->find('css', '.element-editor-header__actions-toggle')->click();
223
        }
224
225
        $button = $popover->find('xpath', sprintf('/button[contains(text(), \'%s\')]', $buttonName));
226
227
        Assert::assertNotNull($button, sprintf('Could not find button labelled "%s"', $buttonName));
228
229
        $button->click();
230
    }
231
232
    /**
233
     * @Given /^I fill in "([^"]*)" for "([^"]*)" for block (\d+)$/
234
     */
235
    public function stepIFillInForForBlock($value, $name, $blockNumber)
236
    {
237
        $block = $this->getSpecificBlock($blockNumber);
238
        $field = $this->findFieldInBlock($block, $name);
239
        $fieldName = $field->getAttribute('name');
240
241
        $isTinyMCE = $field->getAttribute('data-editor') === 'tinyMCE';
242
243
        if ($isTinyMCE) {
244
            $this->cmsContext->stepIFillInTheHtmlFieldWith($fieldName, $value);
245
        } else {
246
            $this->basicContext->iFillinTheRegion($fieldName, $value, 'html');
247
        }
248
    }
249
250
    /**
251
     * @Given /^the "([^"]*)" field for block (\d+) should (not\s*)?contain "([^"]*)"$/
252
     */
253
    public function theFieldForBlockShouldContain($field, $blockNumber, $negate, $content)
254
    {
255
        $block = $this->getSpecificBlock($blockNumber);
256
        $field = $this->findFieldInBlock($block, $field);
257
        $isTinyMCE = $field->getAttribute('data-editor') === 'tinyMCE';
258
259
        if ($isTinyMCE) {
260
            $this->cmsContext->theHtmlFieldShouldContain(
261
                $field->getAttribute('name'),
262
                $negate,
263
                $content
264
            );
265
        } elseif ($negate) {
266
            $this->assertFieldNotContains($field, $content);
267
        } else {
268
            $this->assertFieldContains($field, $content);
269
        }
270
    }
271
272
    /**
273
     * @When I click on the :reportName report
274
     */
275
    public function iClickOnTheReport($reportName)
276
    {
277
        $reportsTable = $this->getSession()->getPage()->find('css', '.all-reports-gridfield .grid-field__table');
278
        Assert::assertNotNull($reportsTable, 'Report table could not be found');
279
280
        $report = $reportsTable->find('xpath', sprintf('//a[contains(text(), \'%s\')]', $reportName));
281
        Assert::assertNotNull($report, 'Specified report "' . $reportName . '" could not be found.');
282
283
        $report->click();
284
285
        // Wait for the report to load
286
        $this->getSession()->wait(5000, 'window.jQuery(".all-reports-gridfield").length === 0');
287
    }
288
289
    /**
290
     * @When I click on the add block button in hover bar area for block :position
291
     */
292
    public function iClickOnHoverBarButton($position)
293
    {
294
        $hoverBarButton = $this->getSpecificHoverBar($position);
295
        $hoverBarButton->click();
296
    }
297
298
    /**
299
     * Returns the blocks from the element editor
300
     *
301
     * @param string $modifier Optional CSS selector modifier
302
     * @return NodeElement[]
303
     */
304
    protected function getBlocks($modifier = '')
305
    {
306
        // Wait for the list to be visible
307
        $this->getSession()->wait(5000, 'window.jQuery(".element-editor .elemental-editor__list").length > 0');
308
309
        // Wait for blocks to be rendered
310
        $this->getSession()->wait(5000, 'window.jQuery(".element-editor__element").length > 0');
311
312
        return $this->getSession()
313
            ->getPage()
314
            ->findAll('css', '.element-editor__element' . $modifier);
315
    }
316
    /**
317
     * Returns the selected element
318
     *
319
     * @param int $position
320
     * @return NodeElement
321
     */
322
    protected function getSpecificBlock($position)
323
    {
324
        $blocks = $this->getBlocks();
325
        /** @var NodeElement $block */
326
        if ($blocks[$position - 1] !== false) {
0 ignored issues
show
introduced by
The condition $blocks[$position - 1] !== false is always true.
Loading history...
327
            return $blocks[$position - 1];
328
        }
329
    }
330
331
    /**
332
     * Returns the archive button for a specific block
333
     *
334
     * @param int $position
335
     * @return NodeElement
336
     */
337
    protected function getArchiveButton($position)
338
    {
339
        $block = $this->getSpecificBlock($position);
340
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
341
342
        $button = $block->find('css', '.element-editor__actions-archive');
343
        Assert::assertNotNull($button, 'Archive button not found');
344
345
        return $button;
346
    }
347
348
    /**
349
     * Returns the publish button for a specific block if it exists
350
     *
351
     * @param int $position
352
     * @return NodeElement|null
353
     */
354
    protected function findPublishButton($position)
355
    {
356
        $block = $this->getSpecificBlock($position);
357
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
358
359
        $button = $block->find('css', '.element-editor__actions-publish');
360
361
        return $button;
362
    }
363
364
    /**
365
     * Returns the unpublish button for a specific block if it exists
366
     *
367
     * @param $position
368
     * @return NodeElement|null
369
     */
370
    protected function findUnpublishButton($position)
371
    {
372
        $block = $this->getSpecificBlock($position);
373
        Assert::assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
374
375
        $button = $block->find('css', '.element-editor__actions-unpublish');
376
377
        return $button;
378
    }
379
380
    /**
381
     * Returns the caret button for a specific block
382
     *
383
     * @param NodeElement $block
384
     * @return NodeElement
385
     */
386
    protected function getCaretButton($block)
387
    {
388
        $button = $block->find('css', '.element-editor-header__expand');
389
        Assert::assertNotNull($button, 'Caret button not found');
390
391
        return $button;
392
    }
393
394
    /**
395
     * @param $block
396
     * @param $name
397
     * @return mixed
398
     */
399
    protected function findFieldInBlock($block, $name)
400
    {
401
        $label = $block->findAll('xpath', sprintf('//label[contains(text(), \'%s\')]', $name));
402
403
        Assert::assertNotCount(0, $label, sprintf('Could not find a label for a field with the content "%s"', $name));
404
        Assert::assertCount(
405
            1,
406
            $label,
407
            sprintf(
408
                'Found more than one label containing the phrase "%s".',
409
                $name
410
            )
411
        );
412
413
        $label = array_shift($label);
414
415
        $fieldId = $label->getAttribute('for');
416
        $field = $block->find('css', '#' . $fieldId);
417
418
        Assert::assertNotNull($field, sprintf(
419
            'Label found matching "%s" but there was no field that has the ID matching the "for" attribute ("#%s")',
420
            $name,
421
            $fieldId
422
        ));
423
424
        return $field;
425
    }
426
427
    /**
428
     * Returns the selected hover bar element
429
     *
430
     * @param int $position
431
     * @return NodeElement
432
     */
433
    protected function getSpecificHoverBar($position)
434
    {
435
        $hoverBarAreas = $this->getSession()
436
            ->getPage()
437
            ->findAll('css', '.element-editor__hover-bar-area');
438
439
        /** @var NodeElement $hoverBarAreas */
440
        if ($hoverBarAreas[$position] !== false) {
441
            return $hoverBarAreas[$position];
442
        }
443
    }
444
}
445