44
55namespace Pest \Browser \Api ;
66
7+ use BadMethodCallException ;
78use Pest \Browser \Execution ;
9+ use Pest \Browser \Page as BrowserPage ;
810use Pest \Browser \Playwright \Locator ;
911use Pest \Browser \Playwright \Page ;
1012use Pest \Browser \Support \GuessLocator ;
@@ -31,11 +33,32 @@ final class Webpage
3133 */
3234 public function __construct (
3335 private readonly Page $ page ,
34- private readonly string $ initialUrl ,
36+ private readonly string | BrowserPage $ initialUrl ,
3537 ) {
3638 //
3739 }
3840
41+ /**
42+ * Dynamically call a method on the browser.
43+ *
44+ * @param array<int, mixed> $arguments
45+ *
46+ * @throws BadMethodCallException
47+ */
48+ public function __call (string $ method , array $ arguments ): self
49+ {
50+ if ($ this ->initialUrl instanceof BrowserPage && method_exists ($ this ->initialUrl , $ method )) {
51+ array_unshift ($ arguments , $ this );
52+
53+ // @phpstan-ignore-next-line method.dynamicName
54+ $ this ->initialUrl ->{$ method }(...$ arguments );
55+
56+ return $ this ;
57+ }
58+
59+ throw new BadMethodCallException ("Call to undefined method [ {$ method }]. " );
60+ }
61+
3962 /**
4063 * Dumps the current page's content and stops the execution.
4164 */
@@ -72,6 +95,18 @@ public function url(): string
7295 return $ this ->page ->url ();
7396 }
7497
98+ /**
99+ * Gets the page's initial URL.
100+ */
101+ public function initialUrl (): string
102+ {
103+ if ($ this ->initialUrl instanceof BrowserPage) {
104+ return $ this ->initialUrl ->url ();
105+ }
106+
107+ return $ this ->initialUrl ;
108+ }
109+
75110 /**
76111 * Submits the first form found on the page.
77112 */
@@ -100,6 +135,8 @@ public function value(string $selector): string
100135
101136 public function within (string $ selector , callable $ callback ): self
102137 {
138+ $ selector = $ this ->resolveShorthandSelector ($ selector );
139+
103140 $ previousScope = $ this ->currentScope ;
104141
105142 $ this ->currentScope = $ previousScope !== null ? $ previousScope .' >> ' .$ selector : $ selector ;
@@ -118,6 +155,20 @@ public function within(string $selector, callable $callback): self
118155 */
119156 private function guessLocator (string $ selector , ?string $ value = null ): Locator
120157 {
158+ $ selector = $ this ->resolveShorthandSelector ($ selector );
159+
121160 return (new GuessLocator ($ this ->page , $ this ->currentScope ))->for ($ selector , $ value );
122161 }
162+
163+ /**
164+ * Resolve the shorthand selector for the given page.
165+ */
166+ private function resolveShorthandSelector (string $ selector ): string
167+ {
168+ $ shorthandElements = $ this ->page ->shorthandElements ();
169+
170+ return str_replace (
171+ array_keys ($ shorthandElements ), array_values ($ shorthandElements ), $ selector
172+ );
173+ }
123174}
0 commit comments