问题
The I should see...
function is an essential feature of Behat but I regularly find myself wanting to write something like this in my scenarios:
Then I should see "Session ID" followed by "3"
Which is my humanly-parsable way of describing 2 pieces of text next to each other in the content. That is to say the first string is the content of any element and the second is the content of it's next immediate sibling.
This would be useful for checking label - value type layouts:
Or if I want to check header - cell value type layouts in tabulated data:
Or even definition title - definition.
Obviously I could add 'id' attributes to every element I want to test but in a complicated page where many parts of the content need testing this starts to feel like I am bloating the markup with single-use attributes.
回答1:
To be able to use...
Then I should see "Session ID" followed by "3"
Add the following methods to your FeatureContext.php
file:
/**
* @Then I should see :textA followed by :textB
*/
public function iShouldSeeFollowedBy($textA, $textB)
{
$content = $this->getSession()->getPage()->getContent();
// Get rid of stuff between script tags
$content = $this->removeContentBetweenTags('script', $content);
// ...and stuff between style tags
$content = $this->removeContentBetweenTags('style', $content);
$content = preg_replace('/<[^>]+>/', ' ',$content);
// Replace line breaks and tabs with a single space character
$content = preg_replace('/[\n\r\t]+/', ' ',$content);
$content = preg_replace('/ {2,}/', ' ',$content);
if (strpos($content,$textA) === false) {
throw new Exception(sprintf('"%s" was not found in the page', $textA));
}
$seeking = $textA . ' ' . $textB;
if (strpos($content,$textA . ' ' . $textB) === false) {
// Be helpful by finding the 10 characters that did follow $textA
preg_match('/' . $textA . ' [^ ]+/',$content,$matches);
throw new Exception(sprintf('"%s" was not found, found "%s" instead', $seeking, $matches[0]));
}
}
/**
* @param string $tagName - The name of the tag, eg. 'script', 'style'
* @param string $content
*
* @return string
*/
private function removeContentBetweenTags($tagName,$content)
{
$parts = explode('<' . $tagName, $content);
$keepers = [];
// We always want to keep the first part
$keepers[] = $parts[0];
foreach ($parts as $part) {
$subparts = explode('</' . $tagName . '>', $part);
if (count($subparts) > 1) {
$keepers[] = $subparts[1];
}
}
return implode('', $keepers);
}
来源:https://stackoverflow.com/questions/49050631/behat-mink-check-for-some-text-followed-by-some-text-in-sibling-elements