AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Drupal Functionaljs Test

skill-trebormc-drupal-ai-agents-drupal-functionaljs-test · by trebormc

>-

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-trebormc-drupal-ai-agents-drupal-functionaljs-test

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-trebormc-drupal-ai-agents-drupal-functionaljs-test)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Drupal Functionaljs Test? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Drupal FunctionalJavascript Test

What It Is

Extends BrowserTestBase but uses a real Chrome browser via WebDriver. JavaScript executes completely. AJAX works. CSS animations are disabled.

Speed: 10-170 seconds per class. Use ONLY when there is no alternative.

Critical Difference from BrowserTestBase

statusCodeEquals() does NOT work in WebDriverTestBase. The Selenium2 driver does not have access to HTTP status codes. Verify access with pageTextContains() or elementExists().

Base Template

adminUser = $this->drupalCreateUser(['access content', 'administer MODULE']);
  }

  public function testAjaxInteraction(): void {
    $this->drupalLogin($this->adminUser);
    $this->drupalGet('route');

    $page = $this->getSession()->getPage();
    $assert = $this->assertSession();

    $page->selectFieldOption('field', 'value');
    $assert->assertWaitOnAjaxRequest();

    $element = $assert->waitForElementVisible('css', '.result');
    $this->assertNotEmpty($element);
  }

}

GOLDEN RULE: Never sleep(), Always Waits

The #1 cause of flaky tests. NEVER sleep(). ALWAYS use waits:

$assert = $this->assertSession();

// Wait for AJAX (most used)
$assert->assertWaitOnAjaxRequest();

// Wait for element in DOM
$element = $assert->waitForElement('css', '.my-element');
$this->assertNotEmpty($element);

// Wait for VISIBLE element
$element = $assert->waitForElementVisible('css', '.dropdown');

// Wait for element to disappear
$assert->waitForElementRemoved('css', '.spinner');

// Specific waits
$assert->waitForButton('Submit');
$assert->waitForLink('Next');
$assert->waitForField('field_name');
$assert->waitForId('my-id');
$assert->waitForText('Done');

// Autocomplete
$assert->waitOnAutocomplete();

// Custom JS condition
$this->getSession()->wait(5000, 'jQuery("#el").is(":visible")');

Pattern: Form with AJAX

public function testDependentSelect(): void {
  $this->drupalLogin($this->adminUser);
  $this->drupalGet('node/add/article');

  $page = $this->getSession()->getPage();
  $assert = $this->assertSession();

  $page->selectFieldOption('field_country', 'ES');
  $assert->assertWaitOnAjaxRequest();

  $cityField = $assert->waitForElementVisible('css', '#edit-field-city');
  $this->assertNotEmpty($cityField);

  $options = $cityField->findAll('css', 'option');
  $values = array_map(fn($o) => $o->getValue(), $options);
  $this->assertContains('madrid', $values);
}

Pattern: Autocomplete (Entity Reference)

public function testAutocomplete(): void {
  $this->drupalCreateNode(['type' => 'article', 'title' => 'Drupal Testing Guide']);

  $this->drupalLogin($this->adminUser);
  $this->drupalGet('node/add/page');

  $page = $this->getSession()->getPage();
  $assert = $this->assertSession();

  $field = $page->findField('field_related[0][target_id]');
  $field->setValue('Drupal');
  $assert->waitOnAutocomplete();

  $suggestions = $page->findAll('css', '.ui-autocomplete li');
  $this->assertGreaterThanOrEqual(1, count($suggestions));
  $suggestions[0]->click();

  $this->assertStringContainsString('Drupal Testing Guide', $field->getValue());
}

Pattern: Modal / Dialog

public function testModal(): void {
  $this->drupalLogin($this->adminUser);
  $this->drupalGet('admin/structure/block');

  $page = $this->getSession()->getPage();
  $assert = $this->assertSession();

  $page->clickLink('Place block');
  $modal = $assert->waitForElementVisible('css', '.ui-dialog');
  $this->assertNotEmpty($modal);

  $modal->fillField('Filter', 'Powered by');
  $assert->waitForText('Powered by Drupal');

  $modal->pressButton('Close');
  $assert->waitForElementRemoved('css', '.ui-dialog');
}

Pattern: Visibility with #states

public function testConditionalVisibility(): void {
  $this->drupalLogin($this->adminUser);
  $this->drupalGet('my-module/settings');

  $page = $this->getSession()->getPage();

  $field = $page->findField('api_key');
  $this->assertFalse($field->isVisible());

  $page->checkField('enable_api');
  $this->assertTrue($field->isVisible());
}

Extra Capabilities

// Verify visibility (not possible in BrowserTestBase)
$this->assertFalse($element->isVisible());

// Execute JS
$this->getSession()->executeScript('document.title = "Test"');

// Evaluate JS (returns value)
$result = $this->getSession()->evaluateScript('return document.title');

// Browser drupalSettings
$settings = $this->getDrupalSettings();

// Screenshot for debug
$this->createScreenshot('/tmp/debug.png');

ChromeDriver Config

Drupal 10.3+ and 11:

Version guard: Drupal 10 (PHPUnit 9) still accepts plain chromeOptions (deprecated since 10.3); in Drupal 11 goog:chromeOptions is MANDATORY (without the goog: prefix it does not work). When in doubt, use goog:chromeOptions — it works on both.

Anti-Patterns

  1. Using sleep(). NEVER.
  2. Using statusCodeEquals(). DOES NOT WORK in WebDriverTestBase.
  3. Not waiting after AJAX. Will pass locally and fail in CI.
  4. Tests with 15+ interactions. That is an E2E flow -> Behat or Playwright.
  5. Testing things that do not need JS. Use Functional test.

Running Tests

ChromeDriver is already available inside the DDEV web container. Do not start it from the agent container (it would not be reachable by PHPUnit in web).

First pick the config form ONCE per session: ssh web test -f phpunit.xml && echo "ROOT" || echo "CORE"

# Form ROOT (project phpunit.xml exists — it must define MINK_DRIVER_ARGS_WEBDRIVER):
ssh web ./vendor/bin/phpunit $DDEV_DOCROOT/modules/custom/MODULE/tests/src/FunctionalJavascript

# Form CORE (no project phpunit.xml — pass ALL env vars explicitly, including the webdriver):
ssh web env SIMPLETEST_DB=mysql://db:db@db/db SIMPLETEST_BASE_URL=http://localhost \
  MINK_DRIVER_ARGS_WEBDRIVER='["chrome", {"browserName":"chrome","goog:chromeOptions":{"args":["--disable-gpu","--headless","--no-sandbox","--disable-dev-shm-usage"]}}, "http://127.0.0.1:9515"]' \
  ./vendor/bin/phpunit -c $DDEV_DOCROOT/core $DDEV_DOCROOT/modules/custom/MODULE/tests/src/FunctionalJavascript

Troubleshooting

| Error | Cause | Fix | |-------|-------|-----| | Connection refused to ChromeDriver | Driver URL wrong or driver not running | Check the URL in MINKDRIVERARGS_WEBDRIVER; verify the driver runs in the web container | | Test flaky (passes sometimes) | Race condition after AJAX/JS | Replace any sleep() with assertWaitOnAjaxRequest() or waitForElementVisible() | | statusCodeEquals() fails/undefined | Not supported in WebDriverTestBase | Assert on page text/elements instead | | Chrome capability errors on D11 | Plain chromeOptions used | Use goog:chromeOptions |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.