Skip to content
Snippets Groups Projects
Verified Commit 2fc7e23e authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3346765 by catch, heddn, Akram Khan, Wim Leers, mondrake: Add...

Issue #3346765 by catch, heddn, Akram Khan, Wim Leers, mondrake: Add PerformanceTestBase for allowing browser performance assertions within FunctionalJavaScriptTests
parent ca17d0ac
No related branches found
No related tags found
No related merge requests found
<?php
namespace Drupal\Tests\system\Functional\Common;
namespace Drupal\Tests\system\FunctionalJavaScript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
use Drupal\node\NodeInterface;
use Drupal\Tests\BrowserTestBase;
/**
* Tests that anonymous users are not served any JavaScript.
......@@ -13,7 +13,7 @@
*
* @group Common
*/
class NoJavaScriptAnonymousTest extends BrowserTestBase {
class NoJavaScriptAnonymousTest extends PerformanceTestBase {
/**
* {@inheritdoc}
......@@ -69,6 +69,7 @@ protected function assertNoJavaScript(): void {
$settings = $this->getDrupalSettings();
$this->assertEmpty($settings, 'drupalSettings is not set.');
$this->assertSession()->responseNotMatches('/\.js/');
$this->assertSame(0, $this->scriptCount);
}
}
<?php
namespace Drupal\Tests\demo_umami\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\PerformanceTestBase;
/**
* Tests demo_umami profile performance.
*
* @group performance
*/
class PerformanceTest extends PerformanceTestBase {
/**
* {@inheritdoc}
*/
protected $profile = 'demo_umami';
/**
* Just load the front page.
*/
public function testFrontPage(): void {
$this->drupalGet('<front>');
$this->assertSession()->pageTextContains('Umami');
$this->assertSame(2, $this->stylesheetCount);
$this->assertSame(1, $this->scriptCount);
}
/**
* Load the front page as a user with access to Tours.
*/
public function testFrontPageTour(): void {
$admin_user = $this->drupalCreateUser(['access tour']);
$this->drupalLogin($admin_user);
$this->drupalGet('<front>');
$this->assertSession()->pageTextContains('Umami');
$this->assertSame(2, $this->stylesheetCount);
$this->assertSame(1, $this->scriptCount);
}
}
<?php
declare(strict_types = 1);
namespace Drupal\FunctionalJavascriptTests;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Collects performance metrics.
*
* @ingroup testing
*/
class PerformanceTestBase extends WebDriverTestBase {
/**
* The number of stylesheets requested.
*/
protected int $stylesheetCount = 0;
/**
* The number of scripts requested.
*/
protected int $scriptCount = 0;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
\Drupal::configFactory()->getEditable('system.performance')
->set('css.preprocess', TRUE)
->set('js.preprocess', TRUE)
->save();
}
/**
* {@inheritdoc}
*/
protected function installModulesFromClassProperty(ContainerInterface $container) {
// Bypass everything that WebDriverTestBase does here to get closer to
// a production configuration.
BrowserTestBase::installModulesFromClassProperty($container);
}
/**
* {@inheritdoc}
*/
protected function getMinkDriverArgs() {
// Add performance logging preferences to the existing driver arguments to
// avoid clobbering anything set via environment variables.
// @see https://chromedriver.chromium.org/logging/performance-log
$parent_driver_args = parent::getMinkDriverArgs();
$driver_args = json_decode($parent_driver_args, TRUE);
$driver_args[1]['goog:loggingPrefs'] = [
'browser' => 'ALL',
'performance' => 'ALL',
'performanceTimeline' => 'ALL',
];
$driver_args[1]['chromeOptions']['perfLoggingPrefs'] = [
'traceCategories' => 'devtools.timeline',
'enableNetwork' => TRUE,
];
return json_encode($driver_args);
}
/**
* {@inheritdoc}
*/
public function drupalGet($path, array $options = [], array $headers = []): string {
// Reset the performance log from any previous HTTP requests. The log is
// cumulative until it is collected explicitly.
$session = $this->getSession();
$session->getDriver()->getWebDriverSession()->log('performance');
$return = parent::drupalGet($path, $options, $headers);
$this->getChromeDriverPerformanceMetrics($path);
return $return;
}
/**
* Gets the chromedriver performance log and extracts metrics from it.
*/
protected function getChromeDriverPerformanceMetrics(string|Url $path): void {
$session = $this->getSession();
$performance_log = $session->getDriver()->getWebDriverSession()->log('performance');
$messages = [];
foreach ($performance_log as $entry) {
$decoded = json_decode($entry['message'], TRUE);
$messages[] = $decoded['message'];
}
$this->collectNetworkData($path, $messages);
}
/**
* Prepares data for assertions.
*
* @param string|\Drupal\Core\Url $path
* The path as passed to static::drupalGet().
* @param array $messages
* The chromedriver performance log messages.
*/
protected function collectNetworkData(string|Url $path, array $messages): void {
$this->stylesheetCount = 0;
$this->scriptCount = 0;
foreach ($messages as $message) {
if ($message['method'] === 'Network.responseReceived') {
if ($message['params']['type'] === 'Stylesheet') {
$this->stylesheetCount++;
}
if ($message['params']['type'] === 'Script') {
$this->scriptCount++;
}
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment