Skip to content

Commit ab31fe7

Browse files
[7.x] Merges develop (#176)
* [7.x] Adds L11 support (#172) * Adds L11 support * Apply fixes from StyleCI * Reverts change * Fixes test suite * Excludes L11 on PHP 8.1 --------- Co-authored-by: StyleCI Bot <bot@styleci.io> * Removes `CreatesApplication` trait (#173) * Fixes workflow * Fixes test suite * Run tests on develop too * [develop] Adds PHPUnit 11 support (#175) * Uses attributes * Adds PHPUnit 11 support * Apply fixes from StyleCI --------- Co-authored-by: StyleCI Bot <bot@styleci.io> * Reverts `CreatesApplication` change * Fixes calling protected method --------- Co-authored-by: StyleCI Bot <bot@styleci.io>
1 parent 1ccbccf commit ab31fe7

35 files changed

+1219
-1068
lines changed

.github/workflows/tests.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches:
66
- master
7+
- develop
78
- '*.x'
89
pull_request:
910
schedule:
@@ -16,10 +17,14 @@ jobs:
1617
strategy:
1718
fail-fast: true
1819
matrix:
19-
php: [8.1, 8.2, 8.3]
20-
laravel: [10]
20+
php: [8.2, 8.3]
21+
phpunit: [10, 11]
22+
laravel: [10, 11]
23+
exclude:
24+
- phpunit: 11
25+
laravel: 10
2126

22-
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }}
27+
name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - Laravel ${{ matrix.laravel }}
2328

2429
steps:
2530
- name: Checkout code
@@ -36,6 +41,7 @@ jobs:
3641

3742
- name: Install dependencies
3843
run: |
44+
composer require phpunit/phpunit:^${{ matrix.phpunit }} --no-update
3945
composer require "laravel/framework=^${{ matrix.laravel }}" --no-update
4046
composer update --prefer-dist --no-interaction --no-progress
4147

composer.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@
1010
}
1111
],
1212
"require": {
13-
"php": "^8.1",
13+
"php": "^8.2",
1414
"ext-dom": "*",
15-
"illuminate/contracts": "^10.0",
16-
"illuminate/database": "^10.0",
17-
"illuminate/http": "^10.0",
18-
"illuminate/support": "^10.0",
19-
"illuminate/testing": "^10.0",
15+
"illuminate/contracts": "^10.0|^11.0",
16+
"illuminate/database": "^10.0|^11.0",
17+
"illuminate/http": "^10.0|^11.0",
18+
"illuminate/support": "^10.0|^11.0",
19+
"illuminate/testing": "^10.0|^11.0",
2020
"mockery/mockery": "^1.0",
21-
"phpunit/phpunit": "^10.0.7",
22-
"symfony/console": "^6.2",
23-
"symfony/css-selector": "^6.2",
24-
"symfony/dom-crawler": "^6.2",
25-
"symfony/http-foundation": "^6.2",
26-
"symfony/http-kernel": "^6.2"
21+
"phpunit/phpunit": "^10.4|^11.0",
22+
"symfony/console": "^6.2|^7.0",
23+
"symfony/css-selector": "^6.2|^7.0",
24+
"symfony/dom-crawler": "^6.2|^7.0",
25+
"symfony/http-foundation": "^6.2|^7.0",
26+
"symfony/http-kernel": "^6.2|^7.0"
2727
},
2828
"require-dev": {
29-
"laravel/framework": "^10.0"
29+
"laravel/framework": "^10.0|^11.0"
3030
},
3131
"autoload": {
3232
"psr-4": {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Laravel\BrowserKitTesting\Constraints\Concerns;
4+
5+
use Symfony\Component\DomCrawler\Crawler;
6+
7+
trait FormFieldConstraint
8+
{
9+
/**
10+
* The name or ID of the element.
11+
*
12+
* @var string
13+
*/
14+
protected readonly string $selector;
15+
16+
/**
17+
* The expected value.
18+
*
19+
* @var string
20+
*/
21+
protected readonly string $value;
22+
23+
/**
24+
* Create a new constraint instance.
25+
*
26+
* @param string $selector
27+
* @param mixed $value
28+
* @return void
29+
*/
30+
public function __construct($selector, $value)
31+
{
32+
$this->selector = $selector;
33+
$this->value = (string) $value;
34+
}
35+
36+
/**
37+
* Get the valid elements.
38+
*
39+
* Multiple elements should be separated by commas without spaces.
40+
*
41+
* @return string
42+
*/
43+
abstract protected function validElements();
44+
45+
/**
46+
* Get the form field.
47+
*
48+
* @param \Symfony\Component\DomCrawler\Crawler $crawler
49+
* @return \Symfony\Component\DomCrawler\Crawler
50+
*
51+
* @throws \PHPUnit\Framework\ExpectationFailedException
52+
*/
53+
protected function field(Crawler $crawler)
54+
{
55+
$field = $crawler->filter(implode(', ', $this->getElements()));
56+
57+
if ($field->count() > 0) {
58+
return $field;
59+
}
60+
61+
$this->fail($crawler, sprintf(
62+
'There is no %s with the name or ID [%s]',
63+
$this->validElements(), $this->selector
64+
));
65+
}
66+
67+
/**
68+
* Get the elements relevant to the selector.
69+
*
70+
* @return array
71+
*/
72+
protected function getElements()
73+
{
74+
$name = str_replace('#', '', $this->selector);
75+
76+
$id = str_replace(['[', ']'], ['\\[', '\\]'], $name);
77+
78+
return collect(explode(',', $this->validElements()))->map(function ($element) use ($name, $id) {
79+
return "{$element}#{$id}, {$element}[name='{$name}']";
80+
})->all();
81+
}
82+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace Laravel\BrowserKitTesting\Constraints\Concerns;
4+
5+
use Symfony\Component\DomCrawler\Crawler;
6+
7+
trait HasElement
8+
{
9+
/**
10+
* The name or ID of the element.
11+
*
12+
* @var string
13+
*/
14+
protected readonly string $selector;
15+
16+
/**
17+
* The attributes the element should have.
18+
*
19+
* @var array
20+
*/
21+
protected readonly array $attributes;
22+
23+
/**
24+
* Create a new constraint instance.
25+
*
26+
* @param string $selector
27+
* @param array $attributes
28+
* @return void
29+
*/
30+
public function __construct($selector, array $attributes = [])
31+
{
32+
$this->selector = $selector;
33+
$this->attributes = $attributes;
34+
}
35+
36+
/**
37+
* Check if the element is found in the given crawler.
38+
*
39+
* @param \Symfony\Component\DomCrawler\Crawler|string $crawler
40+
* @return bool
41+
*/
42+
public function matches($crawler): bool
43+
{
44+
$elements = $this->crawler($crawler)->filter($this->selector);
45+
46+
if ($elements->count() == 0) {
47+
return false;
48+
}
49+
50+
if (empty($this->attributes)) {
51+
return true;
52+
}
53+
54+
$elements = $elements->reduce(function ($element) {
55+
return $this->hasAttributes($element);
56+
});
57+
58+
return $elements->count() > 0;
59+
}
60+
61+
/**
62+
* Determines if the given element has the attributes.
63+
*
64+
* @param \Symfony\Component\DomCrawler\Crawler $element
65+
* @return bool
66+
*/
67+
protected function hasAttributes(Crawler $element)
68+
{
69+
foreach ($this->attributes as $name => $value) {
70+
if (is_numeric($name)) {
71+
if (is_null($element->attr($value))) {
72+
return false;
73+
}
74+
} else {
75+
if ($element->attr($name) != $value) {
76+
return false;
77+
}
78+
}
79+
}
80+
81+
return true;
82+
}
83+
84+
/**
85+
* Returns a string representation of the object.
86+
*
87+
* @return string
88+
*/
89+
public function toString(): string
90+
{
91+
$message = "the element [{$this->selector}]";
92+
93+
if (! empty($this->attributes)) {
94+
$message .= ' with the attributes '.json_encode($this->attributes);
95+
}
96+
97+
return $message;
98+
}
99+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Laravel\BrowserKitTesting\Constraints\Concerns;
4+
5+
use Symfony\Component\DomCrawler\Crawler;
6+
7+
trait HasInElement
8+
{
9+
/**
10+
* The name or ID of the element.
11+
*
12+
* @var string
13+
*/
14+
protected readonly string $element;
15+
16+
/**
17+
* The text expected to be found.
18+
*
19+
* @var string
20+
*/
21+
protected readonly string $text;
22+
23+
/**
24+
* Create a new constraint instance.
25+
*
26+
* @param string $element
27+
* @param string $text
28+
* @return void
29+
*/
30+
public function __construct($element, $text)
31+
{
32+
$this->text = $text;
33+
$this->element = $element;
34+
}
35+
36+
/**
37+
* Check if the source or text is found within the element in the given crawler.
38+
*
39+
* @param \Symfony\Component\DomCrawler\Crawler|string $crawler
40+
* @return bool
41+
*/
42+
public function matches($crawler): bool
43+
{
44+
$elements = $this->crawler($crawler)->filter($this->element);
45+
46+
$pattern = $this->getEscapedPattern($this->text);
47+
48+
foreach ($elements as $element) {
49+
$element = new Crawler($element);
50+
51+
if (preg_match("/$pattern/i", $element->html())) {
52+
return true;
53+
}
54+
}
55+
56+
return false;
57+
}
58+
59+
/**
60+
* Returns the description of the failure.
61+
*
62+
* @return string
63+
*/
64+
protected function getFailureDescription()
65+
{
66+
return sprintf('[%s] contains %s', $this->element, $this->text);
67+
}
68+
69+
/**
70+
* Returns the reversed description of the failure.
71+
*
72+
* @return string
73+
*/
74+
protected function getReverseFailureDescription()
75+
{
76+
return sprintf('[%s] does not contain %s', $this->element, $this->text);
77+
}
78+
}

0 commit comments

Comments
 (0)