Passed
Push — master ( a1de92...1a465b )
by Robbie
03:52
created

tests/Behat/Context/FeatureContext.php (1 issue)

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
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', '.popover-option-set');
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
     * @When I click on the :reportName report
273
     */
274
    public function iClickOnTheReport($reportName)
275
    {
276
        $reportsTable = $this->getSession()->getPage()->find('css', '.all-reports-gridfield .grid-field__table');
277
        assertNotNull($reportsTable, 'Report table could not be found');
278
279
        $report = $reportsTable->find('xpath', sprintf('//a[contains(text(), \'%s\')]', $reportName));
280
        assertNotNull($report, 'Specified report "' . $reportName . '" could not be found.');
281
282
        $report->click();
283
284
        // Wait for the report to load
285
        $this->getSession()->wait(5000, 'window.jQuery(".all-reports-gridfield").length === 0');
286
    }
287
288
    /**
289
     * Returns the blocks from the element editor
290
     *
291
     * @param string $modifier Optional CSS selector modifier
292
     * @return NodeElement[]
293
     */
294
    protected function getBlocks($modifier = '')
295
    {
296
        // Wait for the list to be visible
297
        $this->getSession()->wait(5000, 'window.jQuery(".element-editor .elemental-editor__list").length > 0');
298
299
        // Wait for blocks to be rendered
300
        $this->getSession()->wait(5000, 'window.jQuery(".element-editor__element").length > 0');
301
302
        return $this->getSession()
303
            ->getPage()
304
            ->findAll('css', '.element-editor__element' . $modifier);
305
    }
306
    /**
307
     * Returns the selected element
308
     *
309
     * @param int $position
310
     * @return NodeElement
311
     */
312
    protected function getSpecificBlock($position)
313
    {
314
        $blocks = $this->getBlocks();
315
        /** @var NodeElement $block */
316
        if ($blocks[$position - 1] !== false) {
317
            return $blocks[$position - 1];
318
        }
319
    }
320
321
    /**
322
     * Returns the archive button for a specific block
323
     *
324
     * @param int $position
325
     * @return NodeElement
326
     */
327
    protected function getArchiveButton($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-archive');
333
        assertNotNull($button, 'Archive button not found');
334
335
        return $button;
336
    }
337
338
    /**
339
     * Returns the publish button for a specific block if it exists
340
     *
341
     * @param int $position
342
     * @return NodeElement|null
343
     */
344
    protected function findPublishButton($position)
345
    {
346
        $block = $this->getSpecificBlock($position);
347
        assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
348
349
        $button = $block->find('css', '.element-editor__actions-publish');
350
351
        return $button;
352
    }
353
354
    /**
355
     * Returns the unpublish button for a specific block if it exists
356
     *
357
     * @param $position
358
     * @return NodeElement|null
359
     */
360
    protected function findUnpublishButton($position)
361
    {
362
        $block = $this->getSpecificBlock($position);
363
        assertNotNull($block, 'Block ' . $position . ' was not found in the page.');
364
365
        $button = $block->find('css', '.element-editor__actions-unpublish');
366
367
        return $button;
368
    }
369
370
    /**
371
     * Returns the caret button for a specific block
372
     *
373
     * @param NodeElement $block
374
     * @return NodeElement
375
     */
376
    protected function getCaretButton($block)
377
    {
378
        $button = $block->find('css', '.element-editor-header__expand');
379
        assertNotNull($button, 'Caret button not found');
380
381
        return $button;
382
    }
383
384
    /**
385
     * @param $block
386
     * @param $name
387
     * @return mixed
388
     */
389
    protected function findFieldInBlock($block, $name)
390
    {
391
        $label = $block->findAll('xpath', sprintf('//label[contains(text(), \'%s\')]', $name));
392
393
        assertNotCount(0, $label, sprintf('Could not find a label for a field with the content "%s"', $name));
394
        assertCount(
395
            1,
396
            $label,
397
            sprintf(
398
                'Found more than one label containing the phrase "%s".',
399
                $name
400
            )
401
        );
402
403
        $label = array_shift($label);
404
405
        $fieldId = $label->getAttribute('for');
406
        $field = $block->find('css', '#' . $fieldId);
407
408
        assertNotNull($field, sprintf(
409
            'Label found matching "%s" but there was no field that has the ID matching the "for" attribute ("#%s")',
410
            $name,
411
            $fieldId
412
        ));
413
414
        return $field;
415
    }
416
}
417