| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | <?phpnamespace Tests;use Illuminate\Support\Arr;use Illuminate\Support\Str;use Laravel\Dusk\Browser;use Laravel\Dusk\Component;use PHPUnit\Framework\Assert as PHPUnit;trait BrowserExtension{    public function extendBrowser()    {        $functions = [            // 等待文本可见            'whenTextAvailable' => function ($text, $callbackOrSeconds = null, $seconds = null) {                $callback = null;                if (is_callable($callbackOrSeconds)) {                    $callback = $callbackOrSeconds;                } elseif (is_numeric($callbackOrSeconds)) {                    $seconds = $callbackOrSeconds;                }                $text = Arr::wrap($text);                $message = $this->formatTimeOutMessage('Waited %s seconds for text', implode("', '", $text));                return $this->waitUsing($seconds, 100, function () use ($text, $callback) {                    $results = Str::contains($this->resolver->findOrFail('')->getText(), $text);                    if ($results) {                        $callback && $callback($this);                    }                    return $results;                }, $message);            },            // 等待元素可见            'whenElementAvailable' => function ($selector, $callbackOrSeconds = null, $seconds = null) {                $callback = null;                if (is_callable($callbackOrSeconds)) {                    $callback = $callbackOrSeconds;                } elseif (is_numeric($callbackOrSeconds)) {                    $seconds = $callbackOrSeconds;                }                return $this->whenAvailable($selector, function ($value) use ($callback) {                    $callback && $callback($value);                }, $seconds);            },            // 判断input框是否存在            'hasInput' => function ($field) {                /* @var \Facebook\WebDriver\Remote\RemoteWebElement $element */                $this->resolver->resolveForTyping($field);                return $this;            },            // 判断元素是否不可见            'assertHidden' => function ($selector) {                $fullSelector = $this->resolver->format($selector);                $isHidden = $this->script(                    <<<JSvar display = $('{$fullSelector}').css('display');return display === 'none' || $('{$fullSelector}').is(':hidden');JS                );                PHPUnit::assertTrue(                    (bool) ($isHidden[0] ?? false),                    "Element [{$fullSelector}] is displayed."                );                return $this;            },            // 判断是否是给定组件            'is' => function (Component $component) {                return $this->with($component, function () {                });            },            // 判断文本是否存在,忽略大小写            'assertSeeTextIn' => function (?string $selector, ?string $text) {                $fullSelector = $this->resolver->format($selector);                $element = $this->resolver->findOrFail($selector);                PHPUnit::assertTrue(                    Str::contains(strtolower($element->getText()), strtolower($text)),                    "Did not see expected text [{$text}] within element [{$fullSelector}]."                );                return $this;            },            // 判断文本是否存在,忽略大小写            'assertSeeText' => function (?string $text) {                return $this->assertSeeTextIn('', $text);            },            // 判断全页面中是否存在文本            'assertSeeInBody' => function (?string $text) {                $resolver = clone $this->resolver;                $resolver->prefix = 'html';                $element = $resolver->findOrFail('');                PHPUnit::assertTrue(                    Str::contains(strtolower($element->getText()), strtolower($text)),                    "Did not see expected text [{$text}] within element [html]."                );                return $this;            },            // 等待全页面出现文本            'waitForTextInBody' => function ($text, $seconds = null) {                $text = Arr::wrap($text);                $message = $this->formatTimeOutMessage('Waited %s seconds for text', implode("', '", $text));                $resolver = clone $this->resolver;                $resolver->prefix = 'html';                return $this->waitUsing($seconds, 100, function () use ($resolver, $text) {                    return Str::contains($resolver->findOrFail('')->getText(), $text);                }, $message);            },            // 滚动到页面底部            'scrollToBottom' => function () {                $this->script(                    <<<'JS'$(document).scrollTop($(document).height() - $(window).height());JS                );                return $this;            },            'scrollToTop' => function () {                $this->script(                    <<<'JS'$(document).scrollTop(0);JS                );                return $this;            },        ];        foreach ($functions as $method => $callback) {            Browser::macro($method, $callback);        }    }    public function makeDelayBrowser($browser)    {        return new class($browser)        {            protected $browser;            protected $callbacks = [];            public function __construct(Browser $browser)            {                $this->browser = $browser;            }            public function __call($method, $arguments = [])            {                $this->callbacks[] = [                    'method'    => $method,                    'arguments' => $arguments,                ];                return $this;            }            public function __invoke()            {                $browser = $this->browser;                foreach ($this->callbacks as $value) {                    $method = $value['method'];                    $browser = $browser->{$method}(...$value['arguments']);                }                return $browser;            }        };    }}
 |