Skip to content
Merged
3 changes: 3 additions & 0 deletions src/bundle/Resources/config/services/test/pages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@ services:
Ibexa\AdminUi\Behat\Page\UserSettingsPage: ~

Ibexa\AdminUi\Behat\Page\UserProfilePage: ~

Ibexa\AdminUi\Behat\Page\NotificationsViewAllPage: ~

135 changes: 134 additions & 1 deletion src/lib/Behat/BrowserContext/UserNotificationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Behat\Gherkin\Node\TableNode;
use Ibexa\AdminUi\Behat\Component\UpperMenu;
use Ibexa\AdminUi\Behat\Component\UserNotificationPopup;
use Ibexa\AdminUi\Behat\Page\NotificationsViewAllPage;
use PHPUnit\Framework\Assert;

class UserNotificationContext implements Context
Expand All @@ -22,10 +23,13 @@ class UserNotificationContext implements Context
/** @var \Ibexa\AdminUi\Behat\Component\UserNotificationPopup */
private $userNotificationPopup;

public function __construct(UpperMenu $upperMenu, UserNotificationPopup $userNotificationPopup)
private NotificationsViewAllPage $notificationsViewAllPage;

public function __construct(UpperMenu $upperMenu, UserNotificationPopup $userNotificationPopup, NotificationsViewAllPage $notificationsViewAllPage)
{
$this->upperMenu = $upperMenu;
$this->userNotificationPopup = $userNotificationPopup;
$this->notificationsViewAllPage = $notificationsViewAllPage;
}

/**
Expand All @@ -47,4 +51,133 @@ public function iGoToUserNotificationWithDetails(TableNode $notificationDetails)
$this->userNotificationPopup->verifyIsLoaded();
$this->userNotificationPopup->clickNotification($type, $description);
}

/**
* @Then the notification appears with details:
*/
public function notificationAppearsWithDetails(TableNode $notificationDetails): void
{
$type = $notificationDetails->getHash()[0]['Type'];
$author = $notificationDetails->getHash()[0]['Author'];
$description = $notificationDetails->getHash()[0]['Description'];
$date = $notificationDetails->getHash()[0]['Date'];

$this->userNotificationPopup->verifyIsLoaded();
$this->userNotificationPopup->verifyNotification($type, $author, $description, $date, true);
}

/**
* @When I open notification menu with description :description
*/
public function iOpenNotificationMenu(string $description): void
{
$this->userNotificationPopup->openNotificationMenu($description);
}

/**
* @When I perform the :action action on the notification
*/
public function iPerformNotificationAction(string $action): void
{
$this->userNotificationPopup->clickActionButton($action);
}

/**
* @Then the notification should have :expectedAction action available
*/
public function verifyNotificationAction(string $expectedAction): void
{
$this->userNotificationPopup->findActionButton($expectedAction);
}

/**
* @When I mark all notifications as read
*/
public function markAllNotificationsAsRead(): void
{
$this->userNotificationPopup->verifyIsLoaded();
$this->userNotificationPopup->clickOnMarkAllAsReadButton();
}

/**
* @When I go to the list of all notifications
*/
public function goToAllNotificationsList(): void
{
$this->userNotificationPopup->verifyIsLoaded();
$this->userNotificationPopup->clickViewAllNotificationsButton();
}

/**
* @Then there is :notificationTitle notification on list
*/
public function thereIsNotificationOnList(string $notificationTitle): void
{
$this->notificationsViewAllPage->verifyIsLoaded();
$this->notificationsViewAllPage->verifyNotificationIsOnList($notificationTitle);
}

/**
* @When I mark notification as unread with title :notificationTitle
*/
public function iMarkNotificationAsUnread(string $notificationTitle): void
{
$this->notificationsViewAllPage->markAsUnread($notificationTitle);
}

/**
* @Then the notification with title :notificationTitle has status :notificationStatus
*/
public function verifyNotificationStatus(string $notificationTitle, string $notificationStatus): void
{
Assert::assertEquals($notificationStatus, $this->notificationsViewAllPage->getStatusForNotification($notificationTitle));
}

/**
* @When I go to content of notification with title :notificationTitle
*/
public function iGoToContent(string $notificationTitle): void
{
$this->notificationsViewAllPage->goToContent($notificationTitle);
}

/**
* @When I delete notification with title :notificationTitle
*/
public function iDeleteNotification(string $notificationTitle): void
{
$this->notificationsViewAllPage->deleteNotification($notificationTitle);
}

/**
* @Then an empty notifications state in the popup should be visible
*/
public function emptyNotificationsStateInPopup(): void
{
$this->userNotificationPopup->assertEmptyStateVisible();
}

/**
* @Then an empty notifications state should be visible in the All Notifications view
*/
public function emptyNotificationsStateInAllNotificationsView(): void
{
$this->notificationsViewAllPage->assertEmptyStateVisible();
}

/**
* @Then the notifications popup counter should display :expectedCount
*/
public function iShouldSeeNotificationsCountInPopup(int $expectedCount): void
{
$this->userNotificationPopup->verifyNotificationsCount($expectedCount);
}

/**
* @Then I should see :expectedCount notifications in the All Notifications view
*/
public function thereShouldBeNotificationsInAllNotificationsView(int $expectedCount): void
{
$this->notificationsViewAllPage->verifyNotificationsCount($expectedCount);
}
}
128 changes: 128 additions & 0 deletions src/lib/Behat/Component/UserNotificationPopup.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

use Exception;
use Ibexa\Behat\Browser\Component\Component;
use Ibexa\Behat\Browser\Element\Action\MouseOverAndClick;
use Ibexa\Behat\Browser\Element\Condition\ElementExistsCondition;
use Ibexa\Behat\Browser\Element\Condition\ElementNotExistsCondition;
use Ibexa\Behat\Browser\Element\Criterion\ChildElementTextCriterion;
use Ibexa\Behat\Browser\Element\Criterion\ElementTextCriterion;
use Ibexa\Behat\Browser\Element\ElementInterface;
use Ibexa\Behat\Browser\Locator\VisibleCSSLocator;

class UserNotificationPopup extends Component
Expand Down Expand Up @@ -38,9 +44,123 @@
return;
}

throw new Exception(sprintf('Notification of type: %s with description: %d not found', $expectedType, $expectedDescription));

Check warning on line 47 in src/lib/Behat/Component/UserNotificationPopup.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=ibexa_admin-ui&issues=AZsM5QAmDJ2xiGlfq8nm&open=AZsM5QAmDJ2xiGlfq8nm&pullRequest=1798
}

public function verifyNotification(string $expectedType, string $expectedAuthor, string $expectedDescription, ?string $expectedDate = null, bool $shouldExist = true): void
{
$notifications = $this->getHTMLPage()->setTimeout(5)->findAll($this->getLocator('notificationItem'));

foreach ($notifications as $notification) {
$criteria = [
new ChildElementTextCriterion($this->getLocator('notificationType'), $expectedType),
new ChildElementTextCriterion($this->getLocator('notificationDescriptionTitle'), $expectedAuthor),
new ChildElementTextCriterion($this->getLocator('notificationDescriptionText'), $expectedDescription),
];

if ($expectedDate !== null && $expectedDate !== 'XXXX-XX-XX') {
$criteria[] = new ChildElementTextCriterion($this->getLocator('notificationDate'), $expectedDate);
}

foreach ($criteria as $criterion) {
if (!$criterion->matches($notification)) {
continue 2;
}
}

if ($shouldExist) {
return;
} else {
throw new \Exception(sprintf(

Check warning on line 74 in src/lib/Behat/Component/UserNotificationPopup.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=ibexa_admin-ui&issues=AZsM5QAmDJ2xiGlfq8nn&open=AZsM5QAmDJ2xiGlfq8nn&pullRequest=1798
'Notification of type "%s" with author "%s" and description "%s" should not exist, but was found.',
$expectedType,
$expectedAuthor,
$expectedDescription
));
}
}

if ($shouldExist) {
throw new \Exception(sprintf(

Check warning on line 84 in src/lib/Behat/Component/UserNotificationPopup.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=ibexa_admin-ui&issues=AZsM5QAmDJ2xiGlfq8no&open=AZsM5QAmDJ2xiGlfq8no&pullRequest=1798
'Notification of type "%s" with author "%s" and description "%s" was not found.',
$expectedType,
$expectedAuthor,
$expectedDescription
));
}
}

public function openNotificationMenu(string $expectedDescription): void
{
$this->getHTMLPage()->setTimeout(5)->findAll($this->getLocator('notificationItem'))
->filterBy(new ChildElementTextCriterion($this->getLocator('notificationDescriptionText'), $expectedDescription))
->first()->find($this->getLocator('notificationMenuButton'))->click();

$this->getHTMLPage()
->setTimeout(10)
->waitUntilCondition(
new ElementExistsCondition(
$this->getHTMLPage(),
$this->getLocator('notificationActionsPopup'),
)
);
}

public function clickActionButton(string $buttonText): void
{
$this->getHTMLPage()
->setTimeout(10)
->findAll($this->getLocator('notificationMenuItemContent'))
->filterBy(new ElementTextCriterion($buttonText))->first()->execute(new MouseOverAndClick());

$this->getHTMLPage()
->setTimeout(10)
->waitUntilCondition(
new ElementNotExistsCondition(
$this->getHTMLPage(),
$this->getLocator('notificationActionsPopup')
)
);
}

public function findActionButton(string $buttonText): ?ElementInterface
{
$this->getHTMLPage()
->setTimeout(10)
->waitUntilCondition(
new ElementExistsCondition(
$this->getHTMLPage(),
$this->getLocator('notificationMenuItemContent')
)
);

return $this->getHTMLPage()
->setTimeout(10)
->findAll($this->getLocator('notificationMenuItemContent'))
->filterBy(new ElementTextCriterion($buttonText))
->first();
}

public function assertEmptyStateVisible(): void
{
$this->getHTMLPage()->setTimeout(5)->find($this->getLocator('notificationsEmptyText'))->assert()->isVisible();
}

public function clickOnMarkAllAsReadButton(): void
{
$this->getHTMLPage()->setTimeout(5)->find($this->getLocator('markAllAsReadButton'))->click();
}

public function clickViewAllNotificationsButton(): void
{
$this->getHTMLPage()->setTimeout(3)->find($this->getLocator('viewAllNotificationsButton'))->click();
}

public function verifyNotificationsCount(int $expectedCount): void
{
$this->getHTMLPage()->setTimeout(10)->find($this->getLocator('notificationsCount'))->assert()->textEquals('(' . $expectedCount . ')');
}

public function verifyIsLoaded(): void
{
$this->getHTMLPage()
Expand All @@ -57,6 +177,14 @@
new VisibleCSSLocator('notificationType', '.ibexa-notifications-modal__type-content .type__text'),
new VisibleCSSLocator('notificationDescriptionTitle', '.ibexa-notifications-modal__description .description__title'),
new VisibleCSSLocator('notificationDescriptionText', '.ibexa-notifications-modal__type-content .description__text'),
new VisibleCSSLocator('notificationDate', '.ibexa-notifications-modal__item--date'),
new VisibleCSSLocator('notificationMenuButton', '.ibexa-notifications-modal__actions'),
new VisibleCSSLocator('notificationMenuItemContent', '.ibexa-popup-menu__item-content.ibexa-multilevel-popup-menu__item-content'),
new VisibleCSSLocator('markAllAsReadButton', '.ibexa-notifications-modal__mark-all-read-btn'),
new VisibleCSSLocator('viewAllNotificationsButton', '.ibexa-notifications-modal__view-all-btn'),
new VisibleCSSLocator('notificationActionsPopup', '.ibexa-notification-actions-popup-menu:not(.ibexa-popup-menu--hidden)'),
new VisibleCSSLocator('notificationsEmptyText', '.ibexa-notifications-modal__empty-text'),
new VisibleCSSLocator('notificationsCount', '.ibexa-notifications-modal__count'),
];
}
}
Loading
Loading