create-behat-context — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited create-behat-context (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Read @.ai/Component/Behat/CONTEXT.md for conventions (base class, entity references, stateless steps, bus access).
Create tests/Integration/Behaviour/Features/Context/Domain/{Domain}/{Domain}FeatureContext.php:
AbstractDomainFeatureContext@Given, @When, @Then annotations$this->getCommandBus()->handle(...) for write operations$this->getQueryBus()->handle(...) for read/verification$this->referenceToId($reference) to resolve string references to integer IDs$this->getSharedStorage()->set($reference, $newId)Reference: tests/Integration/Behaviour/Features/Context/Domain/Tax/TaxFeatureContext.php (simple)
/**
* @When I add a {domain} :reference with following properties:
*/
public function iAddDomainWithProperties(string $reference, TableNode $table): void
{
$data = $this->localizeByRows($table);
$command = new Add{Domain}Command(
$data['name'],
(bool) $data['active'],
);
$id = $this->getCommandBus()->handle($command);
$this->getSharedStorage()->set($reference, $id->getValue());
}/**
* @Then {domain} :reference should have the following properties:
*/
public function domainShouldHaveProperties(string $reference, TableNode $table): void
{
$id = $this->referenceToId($reference);
$result = $this->getQueryBus()->handle(new Get{Domain}ForEditing($id));
// Assert each field independently
}The assertion loads the entity fresh from the database — it does NOT rely on state from a previous step.
Errors are tested in two paired steps: the @When step catches the domain exception and stores it via $this->setLastException(...); the next @Then step asserts the stored exception via $this->assertLastErrorIs(...).
/**
* @When I add a {domain} :reference with invalid name
*/
public function addWithInvalidName(string $reference): void
{
try {
$this->getCommandBus()->handle(new Add{Domain}Command(''));
} catch ({Domain}ConstraintException $e) {
$this->setLastException($e);
}
}
/**
* @Then I should get error that {domain} name is invalid
*/
public function assertLastErrorIsInvalidName(): void
{
$this->assertLastErrorIs(
{Domain}ConstraintException::class,
{Domain}ConstraintException::INVALID_NAME, // optional error code
);
}Two safety nets enforced by CommonFeatureContext:
assertLastErrorIs, the checkExpectedExceptionAfterStep @AfterStep hook re-throws it as a RuntimeException — preventing a domain exception from being silently swallowed.cleanStoredExceptionsBeforeScenario (@BeforeScenario) clears any leftover exception so scenarios don't leak state into each other.So: never `try/catch` and ignore — always pair the capture with an assertion in the very next step.
Open tests/Integration/Behaviour/behat.yml and add the context to the domain suite:
domain:
contexts:
- PrestaShop\Tests\Integration\Behaviour\Features\Context\Domain\{Domain}\{Domain}FeatureContextVerify: php vendor/bin/behat --dry-run to confirm all steps are matched.
Conventions (stateless steps, referenceToId, deterministic steps, typed exceptions, error scenarios) are in Behat/CONTEXT.md. Skill-specific reminders:
referenceToId / referencesToIds — not getSharedStorage()->get() directly~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.