Skip to content

Commit e55c81e

Browse files
committed
MNT Add behat tests
1 parent 363a115 commit e55c81e

23 files changed

+284
-2
lines changed

.github/workflows/main.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: Module CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
ci:
9+
uses: silverstripe/github-actions-ci-cd/.github/workflows/[email protected]
10+
with:
11+
run_endtoend: true

.travis.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
version: ~> 1.0
22

33
import:
4-
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range-npm.yml
4+
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range-behat-npm.yml
5+
6+
env:
7+
global:
8+
- COMPOSER_ROOT_VERSION=2.x-dev
9+
# Required for behat testing
10+
- REQUIRE_EXTRA="silverstripe/widgets:^2 silverstripe/comments:^3 silverstripe/content-widget:^2"

behat.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
default:
2+
suites:
3+
blog:
4+
paths:
5+
- "%paths.modules.blog%/tests/behat/features"
6+
contexts:
7+
- SilverStripe\Admin\Tests\Behat\Context\AdminContext
8+
- SilverStripe\BehatExtension\Context\BasicContext
9+
- SilverStripe\BehatExtension\Context\EmailContext
10+
- SilverStripe\BehatExtension\Context\LoginContext
11+
- SilverStripe\Framework\Tests\Behaviour\CmsFormsContext
12+
- SilverStripe\Framework\Tests\Behaviour\CmsUiContext
13+
- SilverStripe\Blog\Tests\Behat\Context\FeatureContext
14+
- SilverStripe\Blog\Tests\Behat\Context\FixtureContext
15+
-
16+
SilverStripe\Blog\Tests\Behat\Context\FixtureContext:
17+
- "%paths.modules.blog%/tests/behat/files/"
18+
19+
extensions:
20+
SilverStripe\BehatExtension\MinkExtension:
21+
default_session: facebook_web_driver
22+
javascript_session: facebook_web_driver
23+
facebook_web_driver:
24+
browser: chrome
25+
wd_host: "http://127.0.0.1:9515"
26+
27+
SilverStripe\BehatExtension\Extension:
28+
screenshot_path: "%paths.base%/artifacts/screenshots"
29+
bootstrap_file: vendor/silverstripe/framework/tests/behat/serve-bootstrap.php

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"autoload": {
2929
"psr-4": {
3030
"SilverStripe\\Blog\\": "src/",
31-
"SilverStripe\\Blog\\Tests\\": "tests/"
31+
"SilverStripe\\Blog\\Tests\\": "tests/php/",
32+
"SilverStripe\\Blog\\Tests\\Behat\\Context\\": "tests/behat/src/"
3233
}
3334
},
3435
"license": "BSD-2-Clause",

tests/behat/_manifest_exclude

Whitespace-only changes.

tests/behat/features/blog.feature

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
Feature: Create a blog
2+
As a website user
3+
I want to create a blog
4+
5+
Background:
6+
Given the "group" "EDITOR group" has permissions "CMS_ACCESS_LeftAndMain"
7+
And I add an extension "SilverStripe\Widgets\Extensions\WidgetPageExtension" to the "Page" class
8+
And I add an extension "SilverStripe\Comments\Extensions\CommentsExtension" to the "Page" class
9+
10+
Given I take a screenshot after every step
11+
Given I dump the rendered HTML after every step
12+
13+
And an "image" "Uploads/file1.jpg"
14+
15+
# Login then logout to created member
16+
And I am logged in with "EDITOR" permissions
17+
And I go to "/Security/login"
18+
And I press the "Log in as someone else" button
19+
And I am logged in with "ADMIN" permissions
20+
21+
# Create a new blog called "New Blog"
22+
When I go to "/admin/pages"
23+
And I press the "Add new" button
24+
And I select the "Blog" radio button
25+
And I press the "Create" button
26+
27+
# Add widgets
28+
And I click the "Widgets" CMS tab
29+
And I uncheck "Inherit Sidebar From Parent"
30+
And I add the "Content" widget
31+
And I add the "Archive" widget
32+
And I add the "Blog Tags" widget
33+
And I fill in the "Content" widget field "Title" with "My content widget title"
34+
And I fill in the "Content" widget HTML field "Content" with "<p>Content widget content</p>"
35+
And I fill in the "Archive" widget field "Title" with "My archive widget title"
36+
And I fill in the "Blog Tags" widget field "Title" with "My blog tags widget title"
37+
And I press the "Save" button
38+
39+
# Add EDITOR as an Editor
40+
And I click the "Settings" CMS tab
41+
And I click the "Users" CMS tab
42+
And I select "EDITOR" from "Editors"
43+
44+
# Publish and logout
45+
And I press the "Publish" button
46+
And I go to "/Security/login"
47+
And I press the "Log in as someone else" button
48+
49+
Scenario: Create a blog post
50+
Given I log in with "[email protected]" and "Secret!123"
51+
52+
# Create a new blog post called "New Post"
53+
When I go to "/admin/pages"
54+
And I follow "New Blog"
55+
And I click the "Blog Posts" CMS tab
56+
And I press the "Add new Blog Post" button
57+
And I fill in "Post Title" with "New Post"
58+
59+
# Add a "Featured image"
60+
And I press the "Choose existing" button
61+
62+
# Select file1.jpg - asset-admin FeatureContext is not available here so use css selector
63+
And I click on the ".gallery__files .gallery-item" element
64+
And I press the "Insert" button
65+
66+
# Add categories and tags
67+
And I click the "Post Options" CMS tab
68+
And I add "My Category" to the "Categories" tag field
69+
And I add "My Tag" to the "Tags" tag field
70+
71+
# Publish the blog post
72+
And I press the "Publish" button
73+
74+
# Test the frontend
75+
When I go to "/new-blog"
76+
Then I should see "New Blog"
77+
And I should see "New Post"
78+
79+
# Widgets
80+
And I should see "My content widget title"
81+
And the rendered HTML should contain "<p>Content widget content</p>"
82+
And I should see "My blog tags widget title"
83+
84+
# Hyperlink to "New Post"
85+
Then the rendered HTML should contain "href=\"/new-blog/new-post"
86+
87+
# Category
88+
And the rendered HTML should contain "href=\"/new-blog/category/my-category\""
89+
90+
# Tag
91+
And the rendered HTML should contain "href=\"/new-blog/tag/my-tag\""
92+
93+
# Test that blog post shows in category view
94+
When I go to "/new-blog/category/my-category"
95+
Then I should see "New Post"
96+
97+
# Test that blog post shows in tag view
98+
When I go to "/new-blog/tag/my-tag"
99+
Then I should see "New Post"
100+
101+
# Commenting
102+
When I fill in "Your name" with "My Name"
103+
And I fill in "Email" with "[email protected]"
104+
And I fill in "Comments" with "My comments"
105+
When I press the "Post" button
106+
Then I should see "New Post"
107+
108+
# Moderation
109+
When I go to "/admin/pages"
110+
And I follow "New Blog"
111+
And I click the "Blog Posts" CMS tab
112+
# Click on the first blog post
113+
And I click on the ".col-Title" element
114+
And I click the "Comments" CMS tab
115+
Then I should see "Approved (1)"
116+
When I click the "Approved (1)" CMS tab
117+
Then I should see "[email protected]"
118+
When I click on the ".action-menu__toggle" element
119+
And I press the "Spam" button
120+
And I wait for 2 seconds
121+
Then I should not see "[email protected]"

tests/behat/files/file1.jpg

2.24 KB
Loading

tests/behat/src/FeatureContext.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace SilverStripe\Blog\Tests\Behat\Context;
4+
5+
use SilverStripe\BehatExtension\Context\SilverStripeContext;
6+
use Behat\Mink\Element\NodeElement;
7+
use PHPUnit\Framework\Assert;
8+
9+
class FeatureContext extends SilverStripeContext
10+
{
11+
/**
12+
* Adds a widget to the blog
13+
*
14+
* @Then /^I add the "([^"]+)" widget$/
15+
* @param $widgetTitle e.g. "Content"
16+
*/
17+
public function iAddTheWidget($widgetTitle)
18+
{
19+
$page = $this->getSession()->getPage();
20+
$h3s = $page->findAll('css', '.availableWidgetsHolder h3');
21+
$found = false;
22+
foreach ($h3s as $h3) {
23+
if ($h3->getText() !== $widgetTitle) {
24+
continue;
25+
}
26+
$found = true;
27+
$h3->click();
28+
}
29+
Assert::assertTrue($found, "Widget {$widgetTitle} was not found");
30+
}
31+
32+
/**
33+
* Fills in a field within a widget
34+
*
35+
* @Then /^I fill in the "([^"]+)" widget field "([^"]+)" with "([^"]+)"$/
36+
* @param $widgetTitle e.g. "Content"
37+
* @param $htmlFragment e.g. "Title"
38+
* @param $value e.g. "Lorem ipsum"
39+
*/
40+
public function iFillInTheWidgetField($widgetTitle, $fieldTitle, $value)
41+
{
42+
$page = $this->getSession()->getPage();
43+
$widget = $this->getWidget($widgetTitle);
44+
$field = $widget->findField($fieldTitle);
45+
Assert::assertNotNull($field, "Widget field {$fieldTitle} was not found");
46+
$field->setValue($value);
47+
}
48+
49+
/**
50+
* Adapated from framework CmsFormsContext stepIFillInTheHtmlFieldWith
51+
*
52+
* @When /^I fill in the "([^"]+)" widget HTML field "([^"]+)" with "([^"]+)"$/
53+
*/
54+
public function stepIFillInTheHtmlFieldWith($widgetTitle, $fieldTitle, $value)
55+
{
56+
$widget = $this->getWidget($widgetTitle);
57+
$field = $this->getDescendantHtmlField($widget, $fieldTitle);
58+
$this->getSession()->evaluateScript(sprintf(
59+
"jQuery('#%s').entwine('ss').getEditor().setContent('%s')",
60+
$field->getAttribute('id'),
61+
addcslashes($value, "'")
62+
));
63+
$this->getSession()->evaluateScript(sprintf(
64+
"jQuery('#%s').entwine('ss').getEditor().save()",
65+
$field->getAttribute('id')
66+
));
67+
}
68+
69+
/**
70+
* @return NodeElement|null
71+
*/
72+
private function getWidget($widgetTitle)
73+
{
74+
$ret = null;
75+
$widgets = $this->getSession()->getPage()->findAll('css', '.usedWidgets .Widget');
76+
foreach ($widgets as $widget) {
77+
$h3 = $widget->find('css', 'h3');
78+
if (!$h3 || $h3->getText() !== $widgetTitle) {
79+
continue;
80+
}
81+
$ret = $widget;
82+
break;
83+
}
84+
Assert::assertNotNull($ret, "Widget edit form for {$widgetTitle} was not found");
85+
return $ret;
86+
}
87+
88+
/**
89+
* @param NodeElement $ancestor
90+
* @param string $locator
91+
* @return NodeElement|null
92+
*/
93+
private function getDescendantHtmlField($element, $locator)
94+
{
95+
$textarea = $element->find('css', "textarea.htmleditor[name='{$locator}']");
96+
if (is_null($textarea)) {
97+
$labels = $element->findAll('xpath', "//label[contains(text(), '{$locator}')]");
98+
Assert::assertCount(1, $labels, "Found more than one html field label containing the phrase '{$locator}}'");
99+
$label = array_shift($labels);
100+
$textarea = $element->find('css', '#' . $label->getAttribute('for'));
101+
}
102+
Assert::assertNotNull($textarea, "HTML field {$locator} not found");
103+
return $textarea;
104+
}
105+
}

tests/behat/src/FixtureContext.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace SilverStripe\Blog\Tests\Behat\Context;
4+
5+
use SilverStripe\BehatExtension\Context\FixtureContext as BaseFixtureContext;
6+
7+
class FixtureContext extends BaseFixtureContext
8+
{
9+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)