-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathAssertableDocument.php
More file actions
123 lines (103 loc) · 3.97 KB
/
AssertableDocument.php
File metadata and controls
123 lines (103 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
declare(strict_types=1);
namespace Ziadoz\AssertableHtml\Dom;
use Dom\Document;
use Dom\HTMLDocument;
use ErrorException;
use PHPUnit\Framework\Assert as PHPUnit;
use Ziadoz\AssertableHtml\Concerns\Asserts\AssertsDocument;
use Ziadoz\AssertableHtml\Concerns\Targetable;
use Ziadoz\AssertableHtml\Concerns\Whenable;
use Ziadoz\AssertableHtml\Concerns\Withable;
use Ziadoz\AssertableHtml\Exceptions\UnableToCreateAssertableDocument;
final readonly class AssertableDocument
{
use AssertsDocument;
use Targetable;
use Whenable;
use Withable;
/** The document's page title. */
public string $title;
/** Create a new assertable document. */
public function __construct(private HTMLDocument|Document $document)
{
$this->title = $this->document->title;
}
/** Get the assertable document HTML. */
public function getHtml(): string
{
return $this->document->saveHtml();
}
/** Dump the document HTML. */
public function dump(): void
{
dump($this->getHtml());
}
/** Dump and die the document HTML. */
public function dd(): never
{
dd($this->getHtml());
}
/*
|--------------------------------------------------------------------------
| Native
|--------------------------------------------------------------------------
*/
/** Create an assertable document from a file. */
public static function createFromFile(string $path, int $options = 0, ?string $overrideEncoding = null): self
{
return self::convertErrorsToExceptions(fn () => new self(HTMLDocument::createFromFile($path, $options, $overrideEncoding)));
}
/** Create an assertable document from a string. */
public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): self
{
return self::convertErrorsToExceptions(fn () => new self(HTMLDocument::createFromString($source, $options, $overrideEncoding)));
}
/** Return the assertable element matching the given selector. */
public function querySelector(string $selector): AssertableElement
{
if (($element = $this->document->querySelector($selector)) === null) {
PHPUnit::fail(sprintf(
"The document doesn't contain an element matching the given selector [%s].",
$selector,
));
}
return new AssertableElement($element)->promote();
}
/** Return assertable elements matching the given selector. */
public function querySelectorAll(string $selector): AssertableElementsList
{
return new AssertableElementsList($this->document->querySelectorAll($selector));
}
/** Return an assertable element matching the given ID. */
public function getElementById(string $id): AssertableElement
{
if (($element = $this->document->getElementById($id)) === null) {
PHPUnit::fail(sprintf(
"The document doesn't contain an element matching the given ID [%s].",
$id,
));
}
return new AssertableElement($element)->promote();
}
/** Return assertable elements matching the given tag. */
public function getElementsByTagName(string $tag): AssertableElementsList
{
return new AssertableElementsList($this->document->getElementsByTagName($tag));
}
/** Convert any PHP errors that occur in the given callback to custom exceptions. */
private static function convertErrorsToExceptions(callable $callback): mixed
{
try {
set_error_handler(function (int $severity, string $message, string $file, int $line): never {
throw new UnableToCreateAssertableDocument(
'Unable to create assertable HTML document.',
previous: new ErrorException($message, 0, $severity, $file, $line),
);
});
return $callback();
} finally {
restore_error_handler();
}
}
}