- Replace all local-variable @var annotations with proper type guards:
- MinkExtension configure closure: build inner array directly
($sessions[$driverType] = [$driverType => ...]) to avoid mixed offset access
- MinkExtension loadSessions: add is_array($session) guard inside foreach
so PHPStan narrows $session from mixed to array before key() call
- DriverFactory::buildDriver @param broadened from array<string, mixed>
to array<mixed> — is_array() only narrows to array<mixed> (key type
unknown), so array<string, mixed> was unreachable at the call site
- MinkAwareInitializer: move @var from inside constructor parameter list
to a proper @param on the method docblock
- SessionsListenerSpec: replace 'goutte' (deleted driver) with
'browserkit_http' as the example default session name
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- FailureShowListener: fix show_tmp_dir fallback '' -> sys_get_temp_dir()
(bug introduced by duplication with MinkContext::showLastResponse)
- SauceLabsFactory: simplify `is_bool($x) ? $x : (bool) $x` -> `(bool) $x`
- MinkExtension::load: extract $baseUrl/$browserName locals to avoid
evaluating the same `?? ''` expression twice per line
- EnvironmentCapabilities: store TRAVIS_JOB_NUMBER and JENKINS_HOME
getenv() results before the switch to avoid double calls per match
- MinkContext: restore PHPDoc comments on all step methods (Example lines
for discoverability); keep PHP attributes, no @Given/@When/@Then tags
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add friendsofphp/php-cs-fixer ^3.75 and phpstan/phpstan ^2.0 to
require-dev; add .php-cs-fixer.dist.php (@Symfony ruleset with
phpdoc_to_comment ignored_tags) and phpstan.neon (level max,
treatPhpDocTypesAsCertain: false)
- Run CS Fixer and PHPStan in every CI matrix job alongside tests
- Add composer scripts: cs, cs-check, phpstan
- Add .php-cs-fixer.cache to .gitignore
- Fix all PHPStan max violations across src/: add return/param types,
narrow mixed config values with is_string()/is_array() guards,
use TaggedNodeInterface for scenario tag access in SessionsListener
- Remove GoutteFactory and its spec — the goutte driver and its
underlying client library are abandoned
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
CI matrix now has a behat-version dimension (stable / 4.x-dev) so both
Behat 3.31 and Behat 4 are tested explicitly. Symfony 8.x rows always
use Behat 4; Symfony 7.4 rows test both versions.
behat.dist.php works with Behat 3.31 too (Behat\Config\Config exists as
a bridge since 3.31), so drop behat.yml.dist and always use the PHP
config — removes the if/else branch from CI and unifies local dev too.
SessionsListener: fix type hint on prepareDefaultMinkSession from
ScenarioLikeTested to ScenarioTested — the method uses getSuite() which
is on LifecycleEvent (not ScenarioLikeTested), and the dispatched events
are ScenarioTested subclasses. Also remove now-unused ScenarioLikeTested
import.
ServiceContainer/MinkExtension: add missing return types (: string,
: void) to all interface method overrides to satisfy Behat 4's stricter
interface signatures.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Mark Goutte, Selenium, Sahi and Zombie driver/support as abandoned
This marks the four drivers as abandoned where the driver implementations are no longer maintained.
* Correctly indent notes so they don't break the enumeration list
* Indent a few more notes that are part of a numerated list
Changing the scalarNode to a booleanNode actually fixes a bug in the latest version of IEDriverServer + Selenium2, which triggers a segmentation fault if the value given for ignoreZoomSetting is a string and not a boolean (which is the case currently).
A simple check for this is to try launching Behat + mink + Selenium2 with Selenium2 + IEDriverServer, with the following defaults:
```yml
default:
suites:
default:
contexts:
- Behat\MinkExtension\Context\MinkContext
extensions:
Behat\MinkExtension:
javascript_session: default
sessions:
default:
selenium2:
browser: "internet explorer"
```
Adding the capabilities with ignoreZoomSetting set to true or false also fixes the issue, but not at the source of the problem.