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

Browser::wrapMinkExpectation()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Zenstruck;
4
5
use Behat\Mink\Driver\DriverInterface;
6
use Behat\Mink\Element\DocumentElement;
7
use Behat\Mink\Mink;
8
use Behat\Mink\Session;
9
use Behat\Mink\WebAssert;
10
use Symfony\Component\Filesystem\Filesystem;
11
use Symfony\Component\VarDumper\VarDumper;
12
use Zenstruck\Browser\Assert;
13
use Zenstruck\Browser\Assert\Assertion\Url;
14
use Zenstruck\Browser\Component;
15
use Zenstruck\Browser\Response;
16
use Zenstruck\Browser\Util\FunctionExecutor;
17
18
/**
19
 * @author Kevin Bond <[email protected]>
20
 */
21
class Browser
22
{
23
    private const SESSION = 'app';
24
25
    private Mink $mink;
26
    private ?string $sourceDir = null;
27
28
    public function __construct(DriverInterface $driver)
29
    {
30
        $this->mink = new Mink([self::SESSION => new Session($driver)]);
31
    }
32
33
    /**
34
     * @return static
35
     */
36
    final public function setSourceDir(string $dir): self
37
    {
38
        $this->sourceDir = $dir;
39
40
        return $this;
41
    }
42
43
    final public function minkSession(): Session
44
    {
45
        return $this->mink->getSession(self::SESSION);
46
    }
47
48
    final public function webAssert(): WebAssert
49
    {
50
        return $this->mink->assertSession(self::SESSION);
51
    }
52
53
    final public function documentElement(): DocumentElement
54
    {
55
        return $this->minkSession()->getPage();
56
    }
57
58
    /**
59
     * @return static
60
     */
61
    final public function visit(string $uri): self
62
    {
63
        $this->minkSession()->visit($uri);
64
65
        return $this;
66
    }
67
68
    /**
69
     * @param array $parts The url parts to check (@see parse_url)
70
     *
71
     * @return static
72
     */
73
    final public function assertOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
74
    {
75
        Assert::that((new Url($this->minkSession()->getCurrentUrl(), $parts))->matches($expected));
76
77
        return $this;
78
    }
79
80
    /**
81
     * @param array $parts The url parts to check (@see parse_url)
82
     *
83
     * @return static
84
     */
85
    final public function assertNotOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
86
    {
87
        Assert::that((new Url($this->minkSession()->getCurrentUrl(), $parts))->notMatches($expected));
88
89
        return $this;
90
    }
91
92
    /**
93
     * @return static
94
     */
95
    final public function assertContains(string $expected): self
96
    {
97
        Assert::wrapMinkExpectation(
98
            fn() => $this->webAssert()->responseContains($expected)
99
        );
100
101
        return $this;
102
    }
103
104
    /**
105
     * @return static
106
     */
107
    final public function assertNotContains(string $expected): self
108
    {
109
        Assert::wrapMinkExpectation(
110
            fn() => $this->webAssert()->responseNotContains($expected)
111
        );
112
113
        return $this;
114
    }
115
116
    /**
117
     * @return static
118
     */
119
    final public function use(callable $callback): self
120
    {
121
        FunctionExecutor::createFor($callback)
122
            ->replaceUntypedArgument($this)
123
            ->replaceTypedArgument(self::class, $this)
124
            ->replaceTypedArgument(Component::class, fn(string $class) => new $class($this))
125
            ->execute()
126
        ;
127
128
        return $this;
129
    }
130
131
    /**
132
     * @return static
133
     */
134
    final public function saveSource(string $filename): self
135
    {
136
        if ($this->sourceDir) {
137
            $filename = \sprintf('%s/%s', \rtrim($this->sourceDir, '/'), \ltrim($filename, '/'));
138
        }
139
140
        (new Filesystem())->dumpFile($filename, $this->response()->raw());
141
142
        return $this;
143
    }
144
145
    /**
146
     * @return static
147
     */
148
    final public function dump(?string $selector = null): self
149
    {
150
        VarDumper::dump($selector ? $this->response()->find($selector) : $this->response()->raw());
151
152
        return $this;
153
    }
154
155
    final public function dd(?string $selector = null): void
156
    {
157
        $this->dump($selector);
158
        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...
159
    }
160
161
    public function dumpCurrentState(string $filename): void
162
    {
163
        $this->saveSource("{$filename}.txt");
164
    }
165
166
    protected function response(): Response
167
    {
168
        return Response::createFor($this->minkSession());
169
    }
170
}
171