component_library-1.0.x-dev/tests/src/FunctionalJavascript/ComponentLibraryAssetTest.php
tests/src/FunctionalJavascript/ComponentLibraryAssetTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\component_library\FunctionalJavascript;
use Drupal\Core\Url;
/**
* Test component library asset functionality.
*
* @group component_library
*/
final class ComponentLibraryAssetTest extends ComponentLibraryTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'olivero';
/**
* The CSS selector of the libraries fieldset.
*/
private string $librariesWrapperSelector = 'details[data-drupal-selector="edit-libraries-wrapper"]';
/**
* List of libraries that will be added and parsed.
*
* @var array|\string[][]
*/
private array $parsedLibraries = [
'olivero/powered-by-block' => ['css/components/powered-by-block.css'],
'olivero/comments' => ['js/comments.js'],
'olivero/local-actions' => ['css/components/action-links.css'],
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
$this->permissions = \array_merge($this->permissions, ['administer component library assets']);
parent::setUp();
}
/**
* Tests creation of assets and registering of corresponding libraries.
*/
public function testCreateLibraryAsset(): void {
$assert = $this->assertSession();
// Check the list builder route and the asset add form.
$this->drupalGet('/admin/structure/component-library/assets');
$assert->linkExists('Add component library asset');
$this->clickLink('Add component library asset');
$assert->elementExists('css', 'form.component-library-asset-form');
$this->drupalGet('/admin/structure/component-library/assets/add');
$page = $this->getSession()->getPage();
$label = 'Link color';
$machine_name = \strtolower(\str_replace(' ', '_', $label));
$page->fillField('label', $label);
// For some reason the following step is required when testing in ddev or
// WebDriver\Exception\ElementNotInteractable: element not interactable
// gets thrown.
$this->getSession()->getDriver()->executeScript("document.querySelector('.admin-link .link').click();");
$page->fillField('id', $machine_name);
$button = $assert->elementExists('css', '#edit-add-css');
$button->press();
$assert->assertWaitOnAjaxRequest();
$css_definition = 'a { color: red !important; }';
$this->fillCodeMirrorEditor($css_definition, '.js-form-item-files-0-code');
$button = $assert->elementExists('css', '#edit-submit');
$button->press();
$this->drupalGet('/admin/structure/component-library/assets');
$assert->pageTextContains($label);
$assert->pageTextContains($machine_name);
$this->drupalGet('/admin/structure/component-library/assets/link_color');
$assert->pageTextContains($css_definition);
/** @var \Drupal\Core\Asset\LibraryDiscoveryCollector $discovery */
$discovery = \Drupal::service('library.discovery.collector');
$discovery->clear();
$libraries = $discovery->getLibrariesByExtension('component_library');
$assert->assert(\array_key_exists('component_library.link_color', $libraries), 'Created library found by library discovery');
}
/**
* Tests parsing of a library from a "real" existing template.
*/
public function testTemplateWithAttachedLibrary(): void {
$assert = $this->assertSession();
$page = $this->getSession()->getPage();
// Open the Override form via toolbar.
$assert->elementExists('css', '#enable-override-mode')->click();
$assert->waitForElementVisible('css', '#override-mode-tray');
// Override Olivero theme's powered by template as it contains an
// attach_library() statement.
$element = $page->find('css', '.override-button:last-child');
$element->click();
$assert->assertWaitOnAjaxRequest();
// Check if the library got parsed as expected.
$page->find('css', $this->librariesWrapperSelector)->click();
$library_keys = \array_keys($this->parsedLibraries);
$assert->pageTextContains($library_keys[0]);
}
/**
* Tests parsing, manually adding and removing libraries.
*/
public function testAttachingRemovingLibraries(): void {
$assert = $this->assertSession();
$page = $this->getSession()->getPage();
$label = 'Library Parsing Page Template';
$edit_path = 'override/library_parsing_page_template/edit';
$added_libraries = [
'olivero/messages' => ['js/messages.js'],
'navigation-primary' => [
'css/components/navigation/nav-primary.css',
'css/components/navigation/nav-primary-button.css',
'js/navigation.js',
'js/second-level-navigation.js',
],
];
// Ensure we can add a component override via the theme settings page.
$theme_settings_page = Url::fromRoute('system.theme_settings_theme', ['theme' => 'olivero']);
$this->drupalGet($theme_settings_page);
$assert->linkExists('Add component override');
$this->clickLink('Add component override');
$assert->elementExists('css', 'form.component-override-form');
// Create a component override for a page node with some twig code that
// attaches libraries.
$page->fillField('label', $label);
$page->selectFieldOption('plugin_container[plugin]', 'content_entity:node');
$assert->assertWaitOnAjaxRequest();
self::assertNotEmpty($assert->waitForElementVisible('css', '[name="plugin_container[view_mode]"]'));
$page->selectFieldOption('plugin_container[view_mode]', 'default');
$assert->assertWaitOnAjaxRequest();
self::assertNotEmpty($assert->waitForElementVisible('css', '[name="plugin_container[override]"]'));
$page->selectFieldOption('plugin_container[override]', 'node__page');
$assert->assertWaitOnAjaxRequest();
$parsed_library_names = \array_keys($this->parsedLibraries);
$this->fillCodeMirrorEditor(
'{{ attach_library("' . $parsed_library_names[0] . '") }}\r\n{{ attach_library("' . $parsed_library_names[1] . '") }}\r\n{{ attach_library("' . $parsed_library_names[2] . '") }}',
);
$page->find('css', $this->librariesWrapperSelector)->click();
// Libraries are only listed once the override is saved.
$assert->pageTextContains('No libraries are attached.');
$button = $assert->elementExists('css', '#edit-submit');
$button->press();
$assert->waitForElementRemoved('css', '.ajax-progress');
// Ensure the theme settings page lists overrides.
$assert->pageTextContains($label);
// Ensure added libraries are listed when editing an override.
$this->drupalGet($edit_path);
$page->find('css', $this->librariesWrapperSelector)->click();
foreach ($this->parsedLibraries as $library => $assets) {
$assert->pageTextContains($library);
}
// Add some libraries via the ajax driven "libraries" dropdown.
foreach ($added_libraries as $library => $assets) {
$page->selectFieldOption('libraries_selector', $library);
$assert->assertWaitOnAjaxRequest();
$page->find('css', $this->librariesWrapperSelector)->click();
$assert->pageTextContains($library);
}
$button = $assert->elementExists('css', '#edit-submit');
$button->press();
$assert->waitForElementRemoved('css', '.ajax-progress');
// Ensure the template was overridden and assets of parsed and added
// libraries are rendered on the node page.
$this->drupalGet("node/{$this->nid}");
foreach (\array_merge($this->parsedLibraries, $added_libraries) as $assets) {
foreach ($assets as $asset_path) {
$assert->responseContains($asset_path);
}
}
}
}
