Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: zenstruck/browser
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.8.1
Choose a base ref
...
head repository: zenstruck/browser
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1.x
Choose a head ref
  • 11 commits
  • 10 files changed
  • 2 contributors

Commits on Apr 1, 2024

  1. bot: fix cs [skip ci]

    kbond committed Apr 1, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    scala-steward Scala Steward
    Copy the full SHA
    33f2a0f View commit details

Commits on Aug 16, 2024

  1. bot: fix cs [skip ci]

    kbond committed Aug 16, 2024
    Copy the full SHA
    3dd63db View commit details

Commits on Oct 9, 2024

  1. minor: sca

    kbond committed Oct 9, 2024
    Copy the full SHA
    d90bad9 View commit details
  2. minor: fix tests

    kbond committed Oct 9, 2024
    Copy the full SHA
    3b4d4a4 View commit details
  3. feat: deprecate foundry integration

    kbond committed Oct 9, 2024
    Copy the full SHA
    d3a52e9 View commit details
  4. Merge pull request #154 from kbond/fixes

    Fixes
    kbond authored Oct 9, 2024
    Copy the full SHA
    49881ed View commit details

Commits on Oct 20, 2024

  1. feat: add BROWSER_ALWAYS_START_WEBSERVER env var (#156)

    kbond authored Oct 20, 2024
    Copy the full SHA
    6175462 View commit details
  2. changelog: update [skip ci]

    kbond committed Oct 20, 2024
    Copy the full SHA
    9603f3d View commit details

Commits on Nov 5, 2024

  1. minor: unpack Foundry 2 proxies (#160)

    - un-deprecated unpacking Foundry 1 proxies
    kbond authored Nov 5, 2024
    Copy the full SHA
    53bbc83 View commit details
  2. changelog: update [skip ci]

    kbond committed Nov 5, 2024
    Copy the full SHA
    a151853 View commit details
  3. bot: fix cs [skip ci]

    kbond committed Nov 5, 2024
    Copy the full SHA
    28b7e1a View commit details
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# CHANGELOG

## [v1.9.1](https://github.com/zenstruck/browser/releases/tag/v1.9.1)

November 5th, 2024 - [v1.9.0...v1.9.1](https://github.com/zenstruck/browser/compare/v1.9.0...v1.9.1)

* 53bbc83 minor: unpack Foundry 2 proxies (#160) by @kbond

## [v1.9.0](https://github.com/zenstruck/browser/releases/tag/v1.9.0)

October 20th, 2024 - [v1.8.1...v1.9.0](https://github.com/zenstruck/browser/compare/v1.8.1...v1.9.0)

* 6175462 feat: add `BROWSER_ALWAYS_START_WEBSERVER` env var (#156) by @kbond
* d3a52e9 feat: deprecate foundry integration (#154) by @kbond
* 3b4d4a4 minor: fix tests (#154) by @kbond
* d90bad9 minor: sca (#154) by @kbond

## [v1.8.1](https://github.com/zenstruck/browser/releases/tag/v1.8.1)

February 21st, 2024 - [v1.8.0...v1.8.1](https://github.com/zenstruck/browser/compare/v1.8.0...v1.8.1)
50 changes: 28 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -320,9 +320,6 @@ $browser
// authenticate a user for subsequent actions
->actingAs($user) // \Symfony\Component\Security\Core\User\UserInterface

// If using zenstruck/foundry, you can pass a factory/proxy
->actingAs(UserFactory::new())

// fail if authenticated
->assertNotAuthenticated()

@@ -332,8 +329,7 @@ $browser
// fails if NOT authenticated as "kbond"
->assertAuthenticated('kbond')

// \Symfony\Component\Security\Core\User\UserInterface or, if using
// zenstruck/foundry, you can pass a factory/proxy
// \Symfony\Component\Security\Core\User\UserInterface
->assertAuthenticated($user)
;
```
@@ -411,7 +407,7 @@ $browser
Make assertions about json responses using [JMESPath expressions](https://jmespath.org/)
See the [JMESPath Tutorials](https://jmespath.org/tutorial.html) to learn more.

> **Note**
> [!NOTE]
> `mtdowling/jmespath.php` is required: `composer require --dev mtdowling/jmespath.php`.
```php
@@ -457,13 +453,21 @@ $json = $browser
;
```

> **Note**
> [!NOTE]
> See the [full `zenstruck/assert` expectation API documentation](https://github.com/zenstruck/assert#expectation-api)
> to see all the methods available on `Zenstruck\Browser\Json`.
### PantherBrowser

*The `PantherBrowser` is experimental in 1.0 and may be subject to BC Breaks.*
> [!NOTE]
> The `PantherBrowser` is experimental in 1.0 and may be subject to BC Breaks.
> [!TIP]
> By default, Panther will not start a web server if it detects one already running
> with the Symfony CLI. This is likely running in your `dev` environment and will cause
> unexpected test failures. Set the env variable `BROWSER_ALWAYS_START_WEBSERVER=1`
> to always start a webserver configured for your current test env when running
> Panther tests.
This browser has the following extra methods:

@@ -547,17 +551,18 @@ class MyTest extends PantherTestCase

There are several environment variables available to configure:

| Variable | Description | Default |
|----------------------------|--------------------------------------------------------------------------------------------|------------------------------------|
| `BROWSER_SOURCE_DIR` | Directory to save source files to. | `./var/browser/source` |
| `BROWSER_SCREENSHOT_DIR` | Directory to save screenshots to (only applies to `PantherBrowser`). | `./var/browser/screenshots` |
| `BROWSER_CONSOLE_LOG_DIR` | Directory to save javascript console logs to (only applies to `PantherBrowser`). | `./var/browser/console-logs` |
| `BROWSER_FOLLOW_REDIRECTS` | Whether to follow redirects by default (only applies to `KernelBrowser`). | `1` _(true)_ |
| `BROWSER_CATCH_EXCEPTIONS` | Whether to catch exceptions by default (only applies to `KernelBrowser`). | `1` _(true)_ |
| `BROWSER_SOURCE_DEBUG` | Whether to add request metadata to written source files (only applies to `KernelBrowser`). | `0` _(false)_ |
| `KERNEL_BROWSER_CLASS` | `KernelBrowser` class to use. | `Zenstruck\Browser\KernelBrowser` |
| `PANTHER_BROWSER_CLASS` | `PantherBrowser` class to use. | `Zenstruck\Browser\PantherBrowser` |
| `PANTHER_NO_HEADLESS` | Disable headless-mode and allow usage of `PantherBrowser::pause()`. | `0` _(false)_ |
| Variable | Description | Default |
|----------------------------------|------------------------------------------------------------------------------------------------------------------------|------------------------------------|
| `BROWSER_SOURCE_DIR` | Directory to save source files to. | `./var/browser/source` |
| `BROWSER_SCREENSHOT_DIR` | Directory to save screenshots to (only applies to `PantherBrowser`). | `./var/browser/screenshots` |
| `BROWSER_CONSOLE_LOG_DIR` | Directory to save javascript console logs to (only applies to `PantherBrowser`). | `./var/browser/console-logs` |
| `BROWSER_FOLLOW_REDIRECTS` | Whether to follow redirects by default (only applies to `KernelBrowser`). | `1` _(true)_ |
| `BROWSER_CATCH_EXCEPTIONS` | Whether to catch exceptions by default (only applies to `KernelBrowser`). | `1` _(true)_ |
| `BROWSER_SOURCE_DEBUG` | Whether to add request metadata to written source files (only applies to `KernelBrowser`). | `0` _(false)_ |
| `KERNEL_BROWSER_CLASS` | `KernelBrowser` class to use. | `Zenstruck\Browser\KernelBrowser` |
| `PANTHER_BROWSER_CLASS` | `PantherBrowser` class to use. | `Zenstruck\Browser\PantherBrowser` |
| `PANTHER_NO_HEADLESS` | Disable headless-mode and allow usage of `PantherBrowser::pause()`. | `0` _(false)_ |
| `BROWSER_ALWAYS_START_WEBSERVER` | Always start a webserver configured for your current test env before running tests (only applies to `PantherBrowser`). | `0` _(false)_ |

## Extending

@@ -822,9 +827,10 @@ Then, depending on the implementation you extended from, set the appropriate env

For the example above, you would set `KERNEL_BROWSER_CLASS=App\Tests\AppBrowser`.

**TIP**: Create a base functional test case so all your tests can use your
custom browser and use the `@method` annotation to ensure your tests can
autocomplete your custom methods:
> [!TIP]
> Create a base functional test case so all your tests can use your
> custom browser and use the `@method` annotation to ensure your tests can
> autocomplete your custom methods:
```php
namespace App\Tests;
7 changes: 3 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -23,15 +23,14 @@
},
"require-dev": {
"dbrekelmans/bdi": "^1.0",
"justinrainbow/json-schema": "^5.2",
"justinrainbow/json-schema": "^5.3",
"mtdowling/jmespath.php": "^2.6",
"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5|^10.4",
"phpunit/phpunit": "^9.6.21|^10.4",
"symfony/mime": "^5.4|^6.0|^7.0",
"symfony/panther": "^1.1|^2.0.1",
"symfony/phpunit-bridge": "^6.0|^7.0",
"symfony/security-bundle": "^5.4|^6.0|^7.0",
"zenstruck/foundry": "^1.30"
"symfony/security-bundle": "^5.4|^6.0|^7.0"
},
"suggest": {
"justinrainbow/json-schema": "Json schema validator. Needed to use Json::assertMatchesSchema().",
33 changes: 22 additions & 11 deletions src/Browser/KernelBrowser.php
Original file line number Diff line number Diff line change
@@ -21,7 +21,8 @@
use Zenstruck\Browser\Session\Driver\BrowserKitDriver;
use Zenstruck\Callback\Parameter;
use Zenstruck\Foundry\Factory;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\Persistence\Proxy;
use Zenstruck\Foundry\Proxy as LegacyProxy;

/**
* @author Kevin Bond <kevinbond@gmail.com>
@@ -127,18 +128,23 @@ final public function withProfiling(): self
}

/**
* @param UserInterface|Proxy<UserInterface>|Factory<UserInterface> $user
* @param UserInterface $user
*
* @return static
*/
public function actingAs(object $user, ?string $firewall = null): self
{
if ($user instanceof Factory) {
$user = $user->create();
if ($user instanceof Factory) { // @phpstan-ignore-line
trigger_deprecation('zenstruck/browser', '1.9', 'Passing a Factory to actingAs() is deprecated, pass the created object instead.');
$user = $user->create(); // @phpstan-ignore-line
}

if ($user instanceof Proxy) {
$user = $user->object();
if ($user instanceof LegacyProxy) { // @phpstan-ignore-line
$user = $user->object(); // @phpstan-ignore-line
}

if ($user instanceof Proxy) { // @phpstan-ignore-line
$user = $user->_real(); // @phpstan-ignore-line
}

if (!$user instanceof UserInterface) {
@@ -151,7 +157,7 @@ public function actingAs(object $user, ?string $firewall = null): self
}

/**
* @param string|UserInterface|Proxy<UserInterface>|Factory<UserInterface>|null $as
* @param string|UserInterface|null $as
*
* @return static
*/
@@ -171,12 +177,17 @@ public function assertAuthenticated($as = null): self
return $this;
}

if ($as instanceof Factory) {
$as = $as->create();
if ($as instanceof Factory) { // @phpstan-ignore-line
trigger_deprecation('zenstruck/browser', '1.9', 'Passing a Factory to assertAuthenticated() is deprecated, pass the created object instead.');
$as = $as->create(); // @phpstan-ignore-line
}

if ($as instanceof LegacyProxy) { // @phpstan-ignore-line
$as = $as->object(); // @phpstan-ignore-line
}

if ($as instanceof Proxy) {
$as = $as->object();
if ($as instanceof Proxy) { // @phpstan-ignore-line
$as = $as->_real(); // @phpstan-ignore-line
}

if ($as instanceof UserInterface) {
5 changes: 5 additions & 0 deletions src/Browser/Test/HasBrowser.php
Original file line number Diff line number Diff line change
@@ -64,6 +64,11 @@ protected function pantherBrowser(array $options = [], array $kernelOptions = []
'console_log_dir' => $_SERVER['BROWSER_CONSOLE_LOG_DIR'] ?? './var/browser/console-logs',
];

if ($_SERVER['BROWSER_ALWAYS_START_WEBSERVER'] ?? null) {
$_SERVER['PANTHER_APP_ENV'] = $_SERVER['APP_ENV'] ?? 'test'; // use current environment
$_SERVER['SYMFONY_PROJECT_DEFAULT_ROUTE_URL'] = ''; // ignore existing server running with Symfony CLI
}

if (self::$primaryPantherClient) {
$browser = new $class(static::createAdditionalPantherClient(), $browserOptions);
} else {
2 changes: 1 addition & 1 deletion src/Browser/Test/LegacyExtension.php
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ private static function normalizeTestName(string $name): string
\preg_match('#^(?<test>[\w:\\\]+) with data set "(?<dataset>.*)"#', $name, $matches);
}

$normalized = \strtr($matches['test'], '\\:', '-_');
$normalized = \strtr($matches['test'], '\\:', '-_'); // @phpstan-ignore-line

if (isset($matches['dataset'])) {
$normalized .= '__data-set-'.\preg_replace('/\W+/', '-', $matches['dataset']);
5 changes: 0 additions & 5 deletions tests/Fixture/Kernel.php
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use Symfony\Component\Security\Core\User\InMemoryUser;
use Zenstruck\Foundry\ZenstruckFoundryBundle;

/**
* @author Kevin Bond <kevinbond@gmail.com>
@@ -173,7 +172,6 @@ public function registerBundles(): iterable
{
yield new FrameworkBundle();
yield new SecurityBundle();
yield new ZenstruckFoundryBundle();
}

protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void
@@ -209,9 +207,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
}

$c->loadFromExtension('security', $security);
$c->loadFromExtension('zenstruck_foundry', [
'auto_refresh_proxies' => false,
]);
$c->register('logger', NullLogger::class); // disable logging
}

2 changes: 1 addition & 1 deletion tests/HttpOptionsTest.php
Original file line number Diff line number Diff line change
@@ -196,7 +196,7 @@ public function json_ajax_constructor_with_no_value(): void
*/
public function create_with_self(): void
{
$options = new class() extends HttpOptions {};
$options = new class extends HttpOptions {};

$this->assertSame($options, HttpOptions::create($options));
}
39 changes: 1 addition & 38 deletions tests/KernelBrowserAuthenticationTest.php
Original file line number Diff line number Diff line change
@@ -17,16 +17,13 @@
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\InMemoryUser;
use Zenstruck\Browser\Test\HasBrowser;
use Zenstruck\Foundry\Test\Factories;

use function Zenstruck\Foundry\anonymous;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class KernelBrowserAuthenticationTest extends KernelTestCase
{
use Factories, HasBrowser;
use HasBrowser;

/**
* @test
@@ -41,54 +38,20 @@ public function can_act_as_user(): void
;
}

/**
* @test
*/
public function can_act_as_user_with_foundry_factory(): void
{
$user = anonymous(InMemoryUser::class, ['username' => 'kevin', 'password' => 'pass']);

$this->browser()
->throwExceptions()
->actingAs($user)
->visit('/user')
->assertSee('user: kevin/pass')
;
}

/**
* @test
*/
public function can_act_as_user_with_foundry_proxy(): void
{
$user = anonymous(InMemoryUser::class)->create(['username' => 'kevin', 'password' => 'pass']);

$this->browser()
->throwExceptions()
->actingAs($user)
->visit('/user')
->assertSee('user: kevin/pass')
;
}

/**
* @test
*/
public function can_make_authentication_assertions(): void
{
$username = 'kevin';
$user = new InMemoryUser('kevin', 'pass');
$factory = anonymous(InMemoryUser::class, ['username' => 'kevin', 'password' => 'pass']);
$proxy = anonymous(InMemoryUser::class)->create(['username' => 'kevin', 'password' => 'pass']);

$this->browser()
->assertNotAuthenticated()
->actingAs($user)
->assertAuthenticated()
->assertAuthenticated($username)
->assertAuthenticated($user)
->assertAuthenticated($factory)
->assertAuthenticated($proxy)
->visit('/user')
->assertAuthenticated()
->assertAuthenticated($username)
Loading