Passed
Push — master ( 7c0d96...cd60cf )
by Robbie
03:07 queued 10s
created

stepIPressTheButtonInTheActionMenuForBlock()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 2
dl 0
loc 15
rs 10
c 0
b 0
f 0
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 SilverStripe\BehatExtension\Context\BasicContext;
7
use SilverStripe\BehatExtension\Context\SilverStripeContext;
8
use SilverStripe\Framework\Tests\Behaviour\CmsFormsContext;
9
10
if (!class_exists(SilverStripeContext::class)) {
11
    return;
12
}
13
14
class FeatureContext extends SilverStripeContext
15
{
16
    /**
17
     * @var CmsFormsContext
18
     */
19
    protected $cmsContext;
20
21
    /**
22
     * @var BasicContext
23
     */
24
    protected $basicContext;
25
26
27
    /** @BeforeScenario */
28
    public function gatherContexts(BeforeScenarioScope $scope)
29
    {
30
        $this->cmsContext = $scope->getEnvironment()->getContext(CmsFormsContext::class);
0 ignored issues
show
Bug introduced by Guy Marriott
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

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