Passed
Pull Request — 1.x (#3)
by Kevin
01:50
created

Browser::assertNotOn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Zenstruck;
4
5
use Behat\Mink\Driver\DriverInterface;
6
use Behat\Mink\Element\DocumentElement;
7
use Behat\Mink\Exception\ExpectationException;
8
use Behat\Mink\Mink;
9
use Behat\Mink\Session;
10
use Behat\Mink\WebAssert;
11
use PHPUnit\Framework\Assert as PHPUnit;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\Assert was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Symfony\Component\Filesystem\Filesystem;
13
use Symfony\Component\VarDumper\VarDumper;
14
use Zenstruck\Browser\Component;
15
use Zenstruck\Browser\Response;
16
use Zenstruck\Browser\Test\Constraint\UrlMatches;
17
use Zenstruck\Browser\Util\FunctionExecutor;
18
19
/**
20
 * @author Kevin Bond <[email protected]>
21
 */
22
class Browser
23
{
24
    private const SESSION = 'app';
25
26
    private Mink $mink;
27
    private ?string $sourceDir = null;
28
29
    public function __construct(DriverInterface $driver)
30
    {
31
        $this->mink = new Mink([self::SESSION => new Session($driver)]);
32
    }
33
34
    /**
35
     * @return static
36
     */
37
    public static function create(callable $factory): self
38
    {
39
        $browser = $factory();
40
41
        if (!$browser instanceof self) {
42
            throw new \RuntimeException(\sprintf('The factory callable must return an instance of "%s".', self::class));
43
        }
44
45
        return $browser;
46
    }
47
48
    /**
49
     * @return static
50
     */
51
    final public function setSourceDir(string $dir): self
52
    {
53
        $this->sourceDir = $dir;
54
55
        return $this;
56
    }
57
58
    final public function minkSession(): Session
59
    {
60
        return $this->mink->getSession(self::SESSION);
61
    }
62
63
    final public function webAssert(): WebAssert
64
    {
65
        return $this->mink->assertSession(self::SESSION);
66
    }
67
68
    final public function documentElement(): DocumentElement
69
    {
70
        return $this->minkSession()->getPage();
71
    }
72
73
    /**
74
     * @return static
75
     */
76
    final public function visit(string $uri): self
77
    {
78
        $this->minkSession()->visit($uri);
79
80
        return $this;
81
    }
82
83
    /**
84
     * @param array $parts The url parts to check (@see parse_url)
85
     *
86
     * @return static
87
     */
88
    final public function assertOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
89
    {
90
        PHPUnit::assertThat($expected, new UrlMatches($this->minkSession()->getCurrentUrl(), $parts));
91
92
        return $this;
93
    }
94
95
    /**
96
     * @param array $parts The url parts to check (@see parse_url)
97
     *
98
     * @return static
99
     */
100
    final public function assertNotOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
101
    {
102
        PHPUnit::assertThat(
103
            $expected,
104
            PHPUnit::logicalNot(new UrlMatches($this->minkSession()->getCurrentUrl(), $parts))
105
        );
106
107
        return $this;
108
    }
109
110
    /**
111
     * @return static
112
     */
113
    final public function assertContains(string $expected): self
114
    {
115
        return $this->wrapMinkExpectation(
116
            fn() => $this->webAssert()->responseContains($expected)
117
        );
118
    }
119
120
    /**
121
     * @return static
122
     */
123
    final public function assertNotContains(string $expected): self
124
    {
125
        return $this->wrapMinkExpectation(
126
            fn() => $this->webAssert()->responseNotContains($expected)
127
        );
128
    }
129
130
    /**
131
     * @return static
132
     */
133
    final public function use(callable $callback): self
134
    {
135
        FunctionExecutor::createFor($callback)
136
            ->replaceUntypedArgument($this)
137
            ->replaceTypedArgument(self::class, $this)
138
            ->replaceTypedArgument(Component::class, fn(string $class) => new $class($this))
139
            ->execute()
140
        ;
141
142
        return $this;
143
    }
144
145
    /**
146
     * @return static
147
     */
148
    final public function saveSource(string $filename): self
149
    {
150
        if ($this->sourceDir) {
151
            $filename = \sprintf('%s/%s', \rtrim($this->sourceDir, '/'), \ltrim($filename, '/'));
152
        }
153
154
        (new Filesystem())->dumpFile($filename, $this->response()->raw());
155
156
        return $this;
157
    }
158
159
    /**
160
     * @return static
161
     */
162
    final public function dump(?string $selector = null): self
163
    {
164
        VarDumper::dump($selector ? $this->response()->find($selector) : $this->response()->raw());
165
166
        return $this;
167
    }
168
169
    final public function dd(?string $selector = null): void
170
    {
171
        $this->dump($selector);
172
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
173
    }
174
175
    public function dumpCurrentState(string $filename): void
176
    {
177
        $this->saveSource("{$filename}.txt");
178
    }
179
180
    protected function response(): Response
181
    {
182
        return Response::createFor($this->minkSession());
183
    }
184
185
    /**
186
     * @return static
187
     */
188
    final protected function wrapMinkExpectation(callable $callback): self
189
    {
190
        try {
191
            $callback();
192
            PHPUnit::assertTrue(true);
193
        } catch (ExpectationException $e) {
194
            PHPUnit::fail($e->getMessage());
195
        }
196
197
        return $this;
198
    }
199
}
200