jqh 5 lat temu
rodzic
commit
b3b2daf7d5
48 zmienionych plików z 1111 dodań i 1111 usunięć
  1. 18 18
      tests/browser-tests/.ide-helper.php
  2. 0 0
      tests/browser-tests/Browser/AuthTest.php
  3. 32 32
      tests/browser-tests/Browser/Components/Component.php
  4. 32 32
      tests/browser-tests/Browser/Components/Form/Field/MultipleSelect2.php
  5. 69 69
      tests/browser-tests/Browser/Components/Form/Field/Select2.php
  6. 120 120
      tests/browser-tests/Browser/Components/Form/Field/Tree.php
  7. 130 130
      tests/browser-tests/Browser/Components/Form/MenuCreationForm.php
  8. 67 67
      tests/browser-tests/Browser/Components/Form/MenuEditForm.php
  9. 60 60
      tests/browser-tests/Browser/IndexTest.php
  10. 40 40
      tests/browser-tests/Browser/InstallTest.php
  11. 141 141
      tests/browser-tests/Browser/MenuTest.php
  12. 55 55
      tests/browser-tests/Browser/Pages/MenuEditPage.php
  13. 0 0
      tests/browser-tests/Browser/Pages/MenuPage.php
  14. 0 0
      tests/browser-tests/Browser/Pages/Page.php
  15. 0 0
      tests/browser-tests/Browser/console/.gitignore
  16. 0 0
      tests/browser-tests/Browser/screenshots/.gitignore
  17. 126 126
      tests/browser-tests/BrowserExtension.php
  18. 0 0
      tests/browser-tests/ChromeProcess.php
  19. 0 0
      tests/browser-tests/Controllers/DropdownController.php
  20. 0 0
      tests/browser-tests/Controllers/ReportController.php
  21. 0 0
      tests/browser-tests/Controllers/UserController.php
  22. 113 113
      tests/browser-tests/CreatesApplication.php
  23. 0 0
      tests/browser-tests/DuskTestCase.php
  24. 89 89
      tests/browser-tests/InteractsWithDatabase.php
  25. 0 0
      tests/browser-tests/Models/File.php
  26. 0 0
      tests/browser-tests/Models/Image.php
  27. 0 0
      tests/browser-tests/Models/MultipleImage.php
  28. 0 0
      tests/browser-tests/Models/Profile.php
  29. 0 0
      tests/browser-tests/Models/Tag.php
  30. 0 0
      tests/browser-tests/Models/Tree.php
  31. 0 0
      tests/browser-tests/Models/User.php
  32. 0 0
      tests/browser-tests/Repositories/Report.php
  33. 0 0
      tests/browser-tests/Repositories/User.php
  34. 7 7
      tests/browser-tests/TestCase.php
  35. 12 12
      tests/browser-tests/helpers.php
  36. 0 0
      tests/browser-tests/resources/assets/test.jpg
  37. 0 0
      tests/browser-tests/resources/config/admin.php
  38. 0 0
      tests/browser-tests/resources/config/filesystems.php
  39. 0 0
      tests/browser-tests/resources/drivers/chromedriver-linux
  40. 0 0
      tests/browser-tests/resources/drivers/chromedriver-mac
  41. 0 0
      tests/browser-tests/resources/drivers/chromedriver-win.exe
  42. 0 0
      tests/browser-tests/resources/lang/en/global.php
  43. 0 0
      tests/browser-tests/resources/lang/en/user.php
  44. 0 0
      tests/browser-tests/resources/migrations/2016_11_22_093148_create_test_tables.php
  45. 0 0
      tests/browser-tests/resources/seeds/UserTableSeeder.php
  46. 0 0
      tests/browser-tests/resources/seeds/factory.php
  47. 0 0
      tests/browser-tests/resources/views/test.blade.php
  48. 0 0
      tests/browser-tests/routes.php

+ 18 - 18
browser-tests/.ide-helper.php → tests/browser-tests/.ide-helper.php

@@ -1,18 +1,18 @@
-<?php
-
-namespace Laravel\Dusk
-{
-    use Laravel\Dusk\Component;
-
-    /**
-     * @method $this whenTextAvailable(string $text, $callbackOrSeconds = null, int $seconds = null)
-     * @method $this whenElementAvailable($selector, $callbackOrSeconds = null, int $seconds = null)
-     * @method $this hasInput($field)
-     * @method $this wait(int $seconds, $callback = null)
-     * @method $this assertHidden($selector)
-     * @method $this assert(Component $component)
-     */
-    class Browser
-    {
-    }
-}
+<?php
+
+namespace Laravel\Dusk
+{
+    use Laravel\Dusk\Component;
+
+    /**
+     * @method $this whenTextAvailable(string $text, $callbackOrSeconds = null, int $seconds = null)
+     * @method $this whenElementAvailable($selector, $callbackOrSeconds = null, int $seconds = null)
+     * @method $this hasInput($field)
+     * @method $this wait(int $seconds, $callback = null)
+     * @method $this assertHidden($selector)
+     * @method $this assert(Component $component)
+     */
+    class Browser
+    {
+    }
+}

+ 0 - 0
browser-tests/Browser/AuthTest.php → tests/browser-tests/Browser/AuthTest.php


+ 32 - 32
browser-tests/Browser/Components/Component.php → tests/browser-tests/Browser/Components/Component.php

@@ -1,32 +1,32 @@
-<?php
-
-namespace Tests\Browser\Components;
-
-use Laravel\Dusk\Browser;
-use Laravel\Dusk\Component as BaseComponent;
-
-abstract class Component extends BaseComponent
-{
-    /**
-     * @param Browser $browser
-     *
-     * @return string
-     */
-    public function parentSelector(Browser $browser)
-    {
-        return str_replace($this->selector(), '', $browser->resolver->prefix);
-    }
-
-    /**
-     * 获取完整的css选择器
-     *
-     * @param Browser $browser
-     * @param string $selector
-     *
-     * @return string
-     */
-    public function formatSelector(Browser $browser, $selector = null)
-    {
-        return $this->parentSelector($browser).' '.($selector ?: $this->selector());
-    }
-}
+<?php
+
+namespace Tests\Browser\Components;
+
+use Laravel\Dusk\Browser;
+use Laravel\Dusk\Component as BaseComponent;
+
+abstract class Component extends BaseComponent
+{
+    /**
+     * @param Browser $browser
+     *
+     * @return string
+     */
+    public function parentSelector(Browser $browser)
+    {
+        return str_replace($this->selector(), '', $browser->resolver->prefix);
+    }
+
+    /**
+     * 获取完整的css选择器
+     *
+     * @param Browser $browser
+     * @param string $selector
+     *
+     * @return string
+     */
+    public function formatSelector(Browser $browser, $selector = null)
+    {
+        return $this->parentSelector($browser).' '.($selector ?: $this->selector());
+    }
+}

+ 32 - 32
browser-tests/Browser/Components/Form/Field/MultipleSelect2.php → tests/browser-tests/Browser/Components/Form/Field/MultipleSelect2.php

@@ -1,32 +1,32 @@
-<?php
-
-namespace Tests\Browser\Components\Form\Field;
-
-use Laravel\Dusk\Browser;
-
-class MultipleSelect2 extends Select2
-{
-    /**
-     * 选中下拉选框
-     *
-     * @param  Browser $browser
-     * @param  array   $values
-     *
-     * @return Browser
-     */
-    public function choose($browser, $values)
-    {
-        $values = implode(',', (array) $values);
-
-//dump($browser->resolver->prefix.' || '.$this->formatSelector($browser));
-
-        $browser->script(
-            <<<JS
-var values = '{$values}';
-$('{$this->formatSelector($browser)}').val(values.split(',')).change();
-JS
-        );
-
-        return $browser;
-    }
-}
+<?php
+
+namespace Tests\Browser\Components\Form\Field;
+
+use Laravel\Dusk\Browser;
+
+class MultipleSelect2 extends Select2
+{
+    /**
+     * 选中下拉选框
+     *
+     * @param  Browser $browser
+     * @param  array   $values
+     *
+     * @return Browser
+     */
+    public function choose($browser, $values)
+    {
+        $values = implode(',', (array) $values);
+
+//dump($browser->resolver->prefix.' || '.$this->formatSelector($browser));
+
+        $browser->script(
+            <<<JS
+var values = '{$values}';
+$('{$this->formatSelector($browser)}').val(values.split(',')).change();
+JS
+        );
+
+        return $browser;
+    }
+}

+ 69 - 69
browser-tests/Browser/Components/Form/Field/Select2.php → tests/browser-tests/Browser/Components/Form/Field/Select2.php

@@ -1,69 +1,69 @@
-<?php
-
-namespace Tests\Browser\Components\Form\Field;
-
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Component;
-
-class Select2 extends Component
-{
-    protected $selector;
-
-    public function __construct($selector = null)
-    {
-        $this->selector = $selector;
-    }
-
-    /**
-     * 获取组件的 root selector
-     *
-     * @return string
-     */
-    public function selector()
-    {
-        return $this->selector;
-    }
-
-    /**
-     * 浏览器包含组件的断言
-     *
-     * @param  Browser  $browser
-     * @return void
-     */
-    public function assert(Browser $browser)
-    {
-        $browser->assertHidden($this->selector())
-            ->assertVisible('@container');
-    }
-
-    /**
-     * 读取组件的元素快捷方式
-     *
-     * @return array
-     */
-    public function elements()
-    {
-        return [
-            '@container' => '.select2'
-        ];
-    }
-
-    /**
-     * 选中下拉选框
-     *
-     * @param  Browser  $browser
-     * @param  mixed    $value
-     *
-     * @return Browser
-     */
-    public function choose(Browser $browser, $value)
-    {
-        $browser->script(
-            <<<JS
-$('{$this->formatSelector($browser)}').val('{$value}').change();
-JS
-        );
-
-        return $browser;
-    }
-}
+<?php
+
+namespace Tests\Browser\Components\Form\Field;
+
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Component;
+
+class Select2 extends Component
+{
+    protected $selector;
+
+    public function __construct($selector = null)
+    {
+        $this->selector = $selector;
+    }
+
+    /**
+     * 获取组件的 root selector
+     *
+     * @return string
+     */
+    public function selector()
+    {
+        return $this->selector;
+    }
+
+    /**
+     * 浏览器包含组件的断言
+     *
+     * @param  Browser  $browser
+     * @return void
+     */
+    public function assert(Browser $browser)
+    {
+        $browser->assertHidden($this->selector())
+            ->assertVisible('@container');
+    }
+
+    /**
+     * 读取组件的元素快捷方式
+     *
+     * @return array
+     */
+    public function elements()
+    {
+        return [
+            '@container' => '.select2'
+        ];
+    }
+
+    /**
+     * 选中下拉选框
+     *
+     * @param  Browser  $browser
+     * @param  mixed    $value
+     *
+     * @return Browser
+     */
+    public function choose(Browser $browser, $value)
+    {
+        $browser->script(
+            <<<JS
+$('{$this->formatSelector($browser)}').val('{$value}').change();
+JS
+        );
+
+        return $browser;
+    }
+}

+ 120 - 120
browser-tests/Browser/Components/Form/Field/Tree.php → tests/browser-tests/Browser/Components/Form/Field/Tree.php

@@ -1,120 +1,120 @@
-<?php
-
-namespace Tests\Browser\Components\Form\Field;
-
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Component;
-
-class Tree extends Component
-{
-    protected $name;
-
-    public function __construct($name = null)
-    {
-        $this->name = $name;
-    }
-
-    /**
-     * 获取组件的 root selector
-     *
-     * @return string
-     */
-    public function selector()
-    {
-        return ".{$this->name}-tree-wrapper";
-    }
-
-    /**
-     * 浏览器包含组件的断言
-     *
-     * @param Browser $browser
-     * @return void
-     */
-    public function assert(Browser $browser)
-    {
-        $browser
-            ->whenElementAvailable('@tree', 2)
-            ->hasInput($this->name);
-    }
-
-    /**
-     * 读取组件的元素快捷方式
-     *
-     * @return array
-     */
-    public function elements()
-    {
-        return [
-            '@container' => $this->selector(),
-            '@tree'      => "{$this->selector()} .da-tree",
-            '@input'     => sprintf('input[name="%s"][type="hidden"]', $this->name),
-        ];
-    }
-
-    /**
-     * 选中下拉选框
-     *
-     * @param Browser $browser
-     * @param mixed   $values
-     *
-     * @return Browser
-     */
-    public function choose(Browser $browser, $values)
-    {
-        $values = json_encode((array) $values);
-
-        $browser->script(<<<JS
-var tree = $('{$this->getTreeSelector($browser)}');        
-        
-tree.jstree("uncheck_all");
-tree.jstree("select_node", {$values});
-JS
-        );
-
-        return $browser;
-    }
-
-    /**
-     * 选中所有
-     *
-     * @param Browser $browser
-     *
-     * @return Browser
-     */
-    public function checkAll(Browser $browser)
-    {
-        $browser->script(<<<JS
-$('{$this->getTreeSelector($browser)}').jstree("check_all");        
-JS
-        );
-
-        return $browser;
-    }
-
-    /**
-     * 取消选中所有
-     *
-     * @param Browser $browser
-     *
-     * @return Browser
-     */
-    public function unCheckAll(Browser $browser)
-    {
-        $browser->script(<<<JS
-$('{$this->getTreeSelector($browser)}').jstree("uncheck_all");        
-JS
-        );
-
-        return $browser;
-    }
-
-    /**
-     * @param \Laravel\Dusk\Browser $browser
-     *
-     * @return string
-     */
-    protected function getTreeSelector(Browser $browser)
-    {
-        return $this->formatSelector($browser, $this->elements()['@tree']);
-    }
-}
+<?php
+
+namespace Tests\Browser\Components\Form\Field;
+
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Component;
+
+class Tree extends Component
+{
+    protected $name;
+
+    public function __construct($name = null)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * 获取组件的 root selector
+     *
+     * @return string
+     */
+    public function selector()
+    {
+        return ".{$this->name}-tree-wrapper";
+    }
+
+    /**
+     * 浏览器包含组件的断言
+     *
+     * @param Browser $browser
+     * @return void
+     */
+    public function assert(Browser $browser)
+    {
+        $browser
+            ->whenElementAvailable('@tree', 2)
+            ->hasInput($this->name);
+    }
+
+    /**
+     * 读取组件的元素快捷方式
+     *
+     * @return array
+     */
+    public function elements()
+    {
+        return [
+            '@container' => $this->selector(),
+            '@tree'      => "{$this->selector()} .da-tree",
+            '@input'     => sprintf('input[name="%s"][type="hidden"]', $this->name),
+        ];
+    }
+
+    /**
+     * 选中下拉选框
+     *
+     * @param Browser $browser
+     * @param mixed   $values
+     *
+     * @return Browser
+     */
+    public function choose(Browser $browser, $values)
+    {
+        $values = json_encode((array) $values);
+
+        $browser->script(<<<JS
+var tree = $('{$this->getTreeSelector($browser)}');        
+        
+tree.jstree("uncheck_all");
+tree.jstree("select_node", {$values});
+JS
+        );
+
+        return $browser;
+    }
+
+    /**
+     * 选中所有
+     *
+     * @param Browser $browser
+     *
+     * @return Browser
+     */
+    public function checkAll(Browser $browser)
+    {
+        $browser->script(<<<JS
+$('{$this->getTreeSelector($browser)}').jstree("check_all");        
+JS
+        );
+
+        return $browser;
+    }
+
+    /**
+     * 取消选中所有
+     *
+     * @param Browser $browser
+     *
+     * @return Browser
+     */
+    public function unCheckAll(Browser $browser)
+    {
+        $browser->script(<<<JS
+$('{$this->getTreeSelector($browser)}').jstree("uncheck_all");        
+JS
+        );
+
+        return $browser;
+    }
+
+    /**
+     * @param \Laravel\Dusk\Browser $browser
+     *
+     * @return string
+     */
+    protected function getTreeSelector(Browser $browser)
+    {
+        return $this->formatSelector($browser, $this->elements()['@tree']);
+    }
+}

+ 130 - 130
browser-tests/Browser/Components/Form/MenuCreationForm.php → tests/browser-tests/Browser/Components/Form/MenuCreationForm.php

@@ -1,130 +1,130 @@
-<?php
-
-namespace Tests\Browser\Components\Form;
-
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Component;
-use Tests\Browser\Components\Form\Field\MultipleSelect2;
-use Tests\Browser\Components\Form\Field\Select2;
-use Tests\Browser\Components\Form\Field\Tree;
-
-class MenuCreationForm extends Component
-{
-    protected $selector;
-
-    public function __construct($selector = 'form[method="POST"]')
-    {
-        $this->selector = $selector;
-    }
-
-    /**
-     * 获取组件的 css selector
-     *
-     * @return string
-     */
-    public function selector()
-    {
-        return $this->selector;
-    }
-
-    /**
-     * 浏览器包含组件的断言
-     *
-     * @param  Browser  $browser
-     * @return void
-     */
-    public function assert(Browser $browser)
-    {
-        $browser->assertSee(__('admin.submit'))
-            ->assertSee(__('admin.reset'))
-            ->within('@form', function (Browser $browser) {
-                $browser
-                    ->assertSee(__('admin.parent_id'))
-                    ->assertSee(__('admin.title'))
-                    ->assertSee(__('admin.icon'))
-                    ->assertSee(__('admin.uri'))
-                    ->assertSee(__('admin.roles'))
-                    ->assertSee(__('admin.permission'))
-                    ->assertSee(__('admin.selectall'))
-                    ->assertSee(__('admin.expand'))
-                    ->hasInput('title')
-                    ->hasInput('icon')
-                    ->hasInput('uri')
-                    ->assertSelected('parent_id', 0)
-                    ->assert(new Tree('permissions'))
-                    ->assert(new Select2('select[name="parent_id"]'))
-                    ->assert(new MultipleSelect2('select[name="roles[]"]'));
-            });
-    }
-
-    /**
-     * 注入表单
-     *
-     * @param Browser $browser
-     * @param array $input
-     *
-     * @return Browser
-     */
-    public function fill(Browser $browser, array $input)
-    {
-        $inputKeys = [
-            'title',
-            'icon',
-            'uri',
-        ];
-
-        $selectKeys = [
-            'parent_id'
-        ];
-
-        $multipleSelectKeys = [
-            'roles',
-        ];
-
-        foreach ($input as $key => $value) {
-            if (in_array($key, $inputKeys, true)) {
-                $browser->type($key, $value);
-
-                continue;
-            }
-
-            if (in_array($key, $selectKeys, true)) {
-                $selector = sprintf('select[name="%s"]', $key);
-                $browser->within(new Select2($selector), function ($browser) use ($value) {
-                    $browser->choose($value);
-                });
-
-                continue;
-            }
-
-            if (in_array($key, $multipleSelectKeys, true)) {
-                $selector = sprintf('select[name="%s[]"]', $key);
-                $browser->within(new MultipleSelect2($selector), function ($browser) use ($value) {
-                    $browser->choose($value);
-                });
-
-                continue;
-            }
-
-            if ($key === 'permissions') {
-                $browser->within(new Tree($key), function ($browser) use ($value) {
-                    $browser->choose($value);
-                });
-            }
-        }
-
-        return $browser;
-    }
-
-    /**
-     * 读取组件的元素快捷方式
-     *
-     * @return array
-     */
-    public function elements()
-    {
-        return [
-            '@form' => $this->selector,
-        ];
-    }
-}
+<?php
+
+namespace Tests\Browser\Components\Form;
+
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Component;
+use Tests\Browser\Components\Form\Field\MultipleSelect2;
+use Tests\Browser\Components\Form\Field\Select2;
+use Tests\Browser\Components\Form\Field\Tree;
+
+class MenuCreationForm extends Component
+{
+    protected $selector;
+
+    public function __construct($selector = 'form[method="POST"]')
+    {
+        $this->selector = $selector;
+    }
+
+    /**
+     * 获取组件的 css selector
+     *
+     * @return string
+     */
+    public function selector()
+    {
+        return $this->selector;
+    }
+
+    /**
+     * 浏览器包含组件的断言
+     *
+     * @param  Browser  $browser
+     * @return void
+     */
+    public function assert(Browser $browser)
+    {
+        $browser->assertSee(__('admin.submit'))
+            ->assertSee(__('admin.reset'))
+            ->within('@form', function (Browser $browser) {
+                $browser
+                    ->assertSee(__('admin.parent_id'))
+                    ->assertSee(__('admin.title'))
+                    ->assertSee(__('admin.icon'))
+                    ->assertSee(__('admin.uri'))
+                    ->assertSee(__('admin.roles'))
+                    ->assertSee(__('admin.permission'))
+                    ->assertSee(__('admin.selectall'))
+                    ->assertSee(__('admin.expand'))
+                    ->hasInput('title')
+                    ->hasInput('icon')
+                    ->hasInput('uri')
+                    ->assertSelected('parent_id', 0)
+                    ->assert(new Tree('permissions'))
+                    ->assert(new Select2('select[name="parent_id"]'))
+                    ->assert(new MultipleSelect2('select[name="roles[]"]'));
+            });
+    }
+
+    /**
+     * 注入表单
+     *
+     * @param Browser $browser
+     * @param array $input
+     *
+     * @return Browser
+     */
+    public function fill(Browser $browser, array $input)
+    {
+        $inputKeys = [
+            'title',
+            'icon',
+            'uri',
+        ];
+
+        $selectKeys = [
+            'parent_id'
+        ];
+
+        $multipleSelectKeys = [
+            'roles',
+        ];
+
+        foreach ($input as $key => $value) {
+            if (in_array($key, $inputKeys, true)) {
+                $browser->type($key, $value);
+
+                continue;
+            }
+
+            if (in_array($key, $selectKeys, true)) {
+                $selector = sprintf('select[name="%s"]', $key);
+                $browser->within(new Select2($selector), function ($browser) use ($value) {
+                    $browser->choose($value);
+                });
+
+                continue;
+            }
+
+            if (in_array($key, $multipleSelectKeys, true)) {
+                $selector = sprintf('select[name="%s[]"]', $key);
+                $browser->within(new MultipleSelect2($selector), function ($browser) use ($value) {
+                    $browser->choose($value);
+                });
+
+                continue;
+            }
+
+            if ($key === 'permissions') {
+                $browser->within(new Tree($key), function ($browser) use ($value) {
+                    $browser->choose($value);
+                });
+            }
+        }
+
+        return $browser;
+    }
+
+    /**
+     * 读取组件的元素快捷方式
+     *
+     * @return array
+     */
+    public function elements()
+    {
+        return [
+            '@form' => $this->selector,
+        ];
+    }
+}

+ 67 - 67
browser-tests/Browser/Components/Form/MenuEditForm.php → tests/browser-tests/Browser/Components/Form/MenuEditForm.php

@@ -1,67 +1,67 @@
-<?php
-
-namespace Tests\Browser\Components\Form;
-
-use Dcat\Admin\Models\Menu;
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Form\Field\MultipleSelect2;
-use Tests\Browser\Components\Form\Field\Select2;
-use Tests\Browser\Components\Form\Field\Tree;
-
-class MenuEditForm extends MenuCreationForm
-{
-    protected $id;
-    protected $selector;
-
-    public function __construct($id = null, $selector = 'form[method="POST"]')
-    {
-        if ($id && ! is_numeric($id)) {
-            $selector = $id;
-            $id = null;
-        }
-
-        $this->id = $id;
-        $this->selector = $selector;
-    }
-
-    /**
-     * 浏览器包含组件的断言
-     *
-     * @param  Browser  $browser
-     * @return void
-     */
-    public function assert(Browser $browser)
-    {
-        $browser->assertSee(__('admin.submit'))
-            ->assertSee(__('admin.reset'))
-            ->within('@form', function (Browser $browser) {
-                $browser
-                    ->assertSee('ID')
-                    ->assertSee(__('admin.parent_id'))
-                    ->assertSee(__('admin.title'))
-                    ->assertSee(__('admin.icon'))
-                    ->assertSee(__('admin.uri'))
-                    ->assertSee(__('admin.roles'))
-                    ->assertSee(__('admin.permission'))
-                    ->assertSee(__('admin.created_at'))
-                    ->assertSee(__('admin.updated_at'))
-                    ->assertSee(__('admin.selectall'))
-                    ->assertSee(__('admin.expand'))
-                    ->hasInput('title')
-                    ->hasInput('icon')
-                    ->hasInput('uri')
-                    ->assert(new Tree('permissions'))
-                    ->assert(new Select2('select[name="parent_id"]'))
-                    ->assert(new MultipleSelect2('select[name="roles[]"]'));
-
-                if (! $this->id) {
-                    return;
-                }
-
-                $menu = Menu::find($this->id);
-                if ($menu) {
-                    $browser->assertSelected('parent_id', $menu->parent_id);
-                }
-            });
-    }
-}
+<?php
+
+namespace Tests\Browser\Components\Form;
+
+use Dcat\Admin\Models\Menu;
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Form\Field\MultipleSelect2;
+use Tests\Browser\Components\Form\Field\Select2;
+use Tests\Browser\Components\Form\Field\Tree;
+
+class MenuEditForm extends MenuCreationForm
+{
+    protected $id;
+    protected $selector;
+
+    public function __construct($id = null, $selector = 'form[method="POST"]')
+    {
+        if ($id && ! is_numeric($id)) {
+            $selector = $id;
+            $id = null;
+        }
+
+        $this->id = $id;
+        $this->selector = $selector;
+    }
+
+    /**
+     * 浏览器包含组件的断言
+     *
+     * @param  Browser  $browser
+     * @return void
+     */
+    public function assert(Browser $browser)
+    {
+        $browser->assertSee(__('admin.submit'))
+            ->assertSee(__('admin.reset'))
+            ->within('@form', function (Browser $browser) {
+                $browser
+                    ->assertSee('ID')
+                    ->assertSee(__('admin.parent_id'))
+                    ->assertSee(__('admin.title'))
+                    ->assertSee(__('admin.icon'))
+                    ->assertSee(__('admin.uri'))
+                    ->assertSee(__('admin.roles'))
+                    ->assertSee(__('admin.permission'))
+                    ->assertSee(__('admin.created_at'))
+                    ->assertSee(__('admin.updated_at'))
+                    ->assertSee(__('admin.selectall'))
+                    ->assertSee(__('admin.expand'))
+                    ->hasInput('title')
+                    ->hasInput('icon')
+                    ->hasInput('uri')
+                    ->assert(new Tree('permissions'))
+                    ->assert(new Select2('select[name="parent_id"]'))
+                    ->assert(new MultipleSelect2('select[name="roles[]"]'));
+
+                if (! $this->id) {
+                    return;
+                }
+
+                $menu = Menu::find($this->id);
+                if ($menu) {
+                    $browser->assertSelected('parent_id', $menu->parent_id);
+                }
+            });
+    }
+}

+ 60 - 60
browser-tests/Browser/IndexTest.php → tests/browser-tests/Browser/IndexTest.php

@@ -1,60 +1,60 @@
-<?php
-
-namespace Tests\Browser;
-
-use Laravel\Dusk\Browser;
-use Tests\TestCase;
-
-/**
- * @group index
- */
-class IndexTest extends TestCase
-{
-    public function testIndex()
-    {
-        $this->browse(function (Browser $browser) {
-            $browser->visit(test_admin_path('/'))
-                ->assertSee('Dashboard')
-                ->assertSee('Description...')
-                ->assertSee('Environment')
-                ->assertSee('PHP version')
-                ->assertSee('Laravel version')
-                ->assertSee('Extensions')
-                ->assertSee('Dependencies')
-                ->assertSee('php')
-                ->assertSee('laravel/framework');
-        });
-    }
-
-    public function testClickMenu()
-    {
-        $this->browse(function (Browser $browser) {
-            $browser->visit(test_admin_path('/'))
-                ->within('.main-sidebar', function (Browser $browser) {
-                    $browser
-                        ->clickLink('Admin')
-                        ->whenTextAvailable('Users', 2)
-                        ->clickLink('Users')
-                        ->assertPathIs(test_admin_path('auth/users'))
-                        ->clickLink('Roles')
-                        ->assertPathIs(test_admin_path('auth/roles'))
-                        ->clickLink('Permission')
-                        ->assertPathIs(test_admin_path('auth/permissions'))
-                        ->clickLink('Menu')
-                        ->assertPathIs(test_admin_path('auth/menu'))
-                        ->clickLink('Operation log')
-                        ->assertPathIs(test_admin_path('auth/logs'))
-                        ->clickLink('Helpers')
-                        ->whenTextAvailable('Extensions', 2)
-                        ->clickLink('Extensions')
-                        ->assertPathIs(test_admin_path('helpers/extensions'))
-                        ->clickLink('Scaffold')
-                        ->assertPathIs(test_admin_path('helpers/scaffold'))
-                        ->clickLink('Routes')
-                        ->assertPathIs(test_admin_path('helpers/routes'))
-                        ->clickLink('Icons')
-                        ->assertPathIs(test_admin_path('helpers/icons'));
-                });
-        });
-    }
-}
+<?php
+
+namespace Tests\Browser;
+
+use Laravel\Dusk\Browser;
+use Tests\TestCase;
+
+/**
+ * @group index
+ */
+class IndexTest extends TestCase
+{
+    public function testIndex()
+    {
+        $this->browse(function (Browser $browser) {
+            $browser->visit(test_admin_path('/'))
+                ->assertSee('Dashboard')
+                ->assertSee('Description...')
+                ->assertSee('Environment')
+                ->assertSee('PHP version')
+                ->assertSee('Laravel version')
+                ->assertSee('Extensions')
+                ->assertSee('Dependencies')
+                ->assertSee('php')
+                ->assertSee('laravel/framework');
+        });
+    }
+
+    public function testClickMenu()
+    {
+        $this->browse(function (Browser $browser) {
+            $browser->visit(test_admin_path('/'))
+                ->within('.main-sidebar', function (Browser $browser) {
+                    $browser
+                        ->clickLink('Admin')
+                        ->whenTextAvailable('Users', 2)
+                        ->clickLink('Users')
+                        ->assertPathIs(test_admin_path('auth/users'))
+                        ->clickLink('Roles')
+                        ->assertPathIs(test_admin_path('auth/roles'))
+                        ->clickLink('Permission')
+                        ->assertPathIs(test_admin_path('auth/permissions'))
+                        ->clickLink('Menu')
+                        ->assertPathIs(test_admin_path('auth/menu'))
+                        ->clickLink('Operation log')
+                        ->assertPathIs(test_admin_path('auth/logs'))
+                        ->clickLink('Helpers')
+                        ->whenTextAvailable('Extensions', 2)
+                        ->clickLink('Extensions')
+                        ->assertPathIs(test_admin_path('helpers/extensions'))
+                        ->clickLink('Scaffold')
+                        ->assertPathIs(test_admin_path('helpers/scaffold'))
+                        ->clickLink('Routes')
+                        ->assertPathIs(test_admin_path('helpers/routes'))
+                        ->clickLink('Icons')
+                        ->assertPathIs(test_admin_path('helpers/icons'));
+                });
+        });
+    }
+}

+ 40 - 40
browser-tests/Browser/InstallTest.php → tests/browser-tests/Browser/InstallTest.php

@@ -1,40 +1,40 @@
-<?php
-
-namespace Tests\Browser;
-
-use Tests\TestCase;
-
-/**
- * @group install
- */
-class InstallTest extends TestCase
-{
-    protected $login = false;
-
-    public function testInstalledDirectories()
-    {
-        $this->assertFileExists(admin_path());
-
-        $this->assertFileExists(admin_path('Controllers'));
-
-        $this->assertFileExists(admin_path('routes.php'));
-
-        $this->assertFileExists(admin_path('bootstrap.php'));
-
-        $this->assertFileExists(admin_path('Controllers/HomeController.php'));
-
-        $this->assertFileExists(admin_path('Controllers/AuthController.php'));
-
-        $this->assertFileExists(config_path('admin.php'));
-
-        $this->assertFileExists(public_path('vendor/dcat-admin'));
-
-        $this->assertFileExists(database_path('migrations/2016_01_04_173148_create_admin_tables.php'));
-
-        $this->assertFileExists(resource_path('lang/en/admin.php'));
-
-        $this->assertFileExists(resource_path('lang/zh-CN/admin.php'));
-
-        $this->assertFileExists(resource_path('lang/zh-CN/global.php'));
-    }
-}
+<?php
+
+namespace Tests\Browser;
+
+use Tests\TestCase;
+
+/**
+ * @group install
+ */
+class InstallTest extends TestCase
+{
+    protected $login = false;
+
+    public function testInstalledDirectories()
+    {
+        $this->assertFileExists(admin_path());
+
+        $this->assertFileExists(admin_path('Controllers'));
+
+        $this->assertFileExists(admin_path('routes.php'));
+
+        $this->assertFileExists(admin_path('bootstrap.php'));
+
+        $this->assertFileExists(admin_path('Controllers/HomeController.php'));
+
+        $this->assertFileExists(admin_path('Controllers/AuthController.php'));
+
+        $this->assertFileExists(config_path('admin.php'));
+
+        $this->assertFileExists(public_path('vendor/dcat-admin'));
+
+        $this->assertFileExists(database_path('migrations/2016_01_04_173148_create_admin_tables.php'));
+
+        $this->assertFileExists(resource_path('lang/en/admin.php'));
+
+        $this->assertFileExists(resource_path('lang/zh-CN/admin.php'));
+
+        $this->assertFileExists(resource_path('lang/zh-CN/global.php'));
+    }
+}

+ 141 - 141
browser-tests/Browser/MenuTest.php → tests/browser-tests/Browser/MenuTest.php

@@ -1,141 +1,141 @@
-<?php
-
-namespace Tests\Browser;
-
-use Dcat\Admin\Models\Menu;
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Form\MenuEditForm;
-use Tests\Browser\Components\Form\Field\MultipleSelect2;
-use Tests\Browser\Components\Form\Field\Select2;
-use Tests\Browser\Pages\MenuEditPage;
-use Tests\Browser\Pages\MenuPage;
-use Tests\TestCase;
-
-/**
- * @group menu
- */
-class MenuTest extends TestCase
-{
-    public function testMenuIndex()
-    {
-        $this->browse(function (Browser $browser) {
-            $browser->visit(new MenuPage());
-        });
-    }
-
-    public function testAddMenu()
-    {
-        $this->browse(function (Browser $browser) {
-            $item = [
-                'parent_id'   => '0',
-                'title'       => 'Test',
-                'uri'         => 'test',
-                'icon'        => 'fa-user',
-                'roles'       => [1],
-                'permissions' => [4, 5],
-            ];
-
-            $browser
-                ->visit(new MenuPage())
-                ->newMenu($item)
-                ->waitForText(__('admin.save_succeeded'), 2);
-
-            $newMenuId = Menu::query()->orderByDesc('id')->first()->id;
-
-            // 检测是否写入数据库
-            $this->assertDatabase($newMenuId, $item);
-            $this->assertEquals(8, Menu::count());
-        });
-    }
-
-    public function testDeleteMenu()
-    {
-        $this->delete('admin/auth/menu/8');
-        $this->assertEquals(7, Menu::count());
-    }
-
-    public function testEditMenu()
-    {
-        $this->browse(function (Browser $browser) {
-            $browser->visit(new MenuEditPage(1))
-                ->type('title', 'blablabla')
-                ->press(__('admin.submit'))
-                ->waitForLocation(test_admin_path('auth/menu'), 2);
-
-            $this->seeInDatabase(config('admin.database.menu_table'), ['title' => 'blablabla'])
-                ->assertEquals(7, Menu::count());
-        });
-    }
-
-    public function testEditMenuParent()
-    {
-        $this->browse(function (Browser $browser) {
-            $id = 5;
-
-            $browser->visit(new MenuEditPage($id))
-                ->within(new Select2('select[name="parent_id"]'), function ($browser) use ($id) {
-                    $browser->choose($id);
-                })
-                ->press(__('admin.submit'))
-                ->waitForText('500 Internal Server Error', 2);
-        });
-    }
-
-    public function testQuickEditMenu()
-    {
-        $this->browse(function (Browser $browser) {
-            $id = 5;
-
-            $updates = [
-                'title'       => 'balabala',
-                'icon'        => 'fa-list',
-                'parent_id'   => 0,
-                'roles'       => 1,
-                'permissions' => [4, 5, 6],
-            ];
-
-            $browser->visit(new MenuPage())
-                ->within(sprintf('li[data-id="%d"]', $id), function (Browser $browser) {
-                    $browser->click('.tree-quick-edit');
-                })
-                ->whenAvailable('.layui-layer-page', function (Browser $browser) use ($id, $updates) {
-                    $browser->whenElementAvailable(new MenuEditForm($id), function (Browser $browser) use ($updates) {
-                        // 检测表单
-                        $browser->fill($updates);
-                    }, 3)
-                        ->assertSee(__('admin.edit'))
-                        ->click('div')
-                        ->whenElementAvailable(new MultipleSelect2('select[name="roles[]"]'), function (Browser $browser) {
-                            $browser->choose(1);
-                        }, 2)
-                        ->clickLink(__('admin.submit'));
-                }, 3)
-                ->waitForText(__('admin.update_succeeded'), 3)
-                ->waitForLocation(test_admin_path('auth/menu'), 2)
-                ->waitForText('balabala', 2);
-
-            // 检测是否写入数据库
-            $this->assertDatabase($id, $updates);
-        });
-    }
-
-    private function assertDatabase($id, $updates)
-    {
-        $roles = $updates['roles'];
-        $permissions = $updates['permissions'];
-
-        unset($updates['roles'], $updates['permissions']);
-
-        // 检测是否写入数据库
-        return $this
-            ->seeInDatabase(config('admin.database.menu_table'), $updates)
-            ->seeInDatabase(
-                config('admin.database.role_menu_table'),
-                ['role_id' => $roles, 'menu_id' => $id]
-            )
-            ->seeInDatabase(
-                config('admin.database.permission_menu_table'),
-                ['permission_id' => $permissions, 'menu_id' => $id]
-            );
-    }
-}
+<?php
+
+namespace Tests\Browser;
+
+use Dcat\Admin\Models\Menu;
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Form\MenuEditForm;
+use Tests\Browser\Components\Form\Field\MultipleSelect2;
+use Tests\Browser\Components\Form\Field\Select2;
+use Tests\Browser\Pages\MenuEditPage;
+use Tests\Browser\Pages\MenuPage;
+use Tests\TestCase;
+
+/**
+ * @group menu
+ */
+class MenuTest extends TestCase
+{
+    public function testMenuIndex()
+    {
+        $this->browse(function (Browser $browser) {
+            $browser->visit(new MenuPage());
+        });
+    }
+
+    public function testAddMenu()
+    {
+        $this->browse(function (Browser $browser) {
+            $item = [
+                'parent_id'   => '0',
+                'title'       => 'Test',
+                'uri'         => 'test',
+                'icon'        => 'fa-user',
+                'roles'       => [1],
+                'permissions' => [4, 5],
+            ];
+
+            $browser
+                ->visit(new MenuPage())
+                ->newMenu($item)
+                ->waitForText(__('admin.save_succeeded'), 2);
+
+            $newMenuId = Menu::query()->orderByDesc('id')->first()->id;
+
+            // 检测是否写入数据库
+            $this->assertDatabase($newMenuId, $item);
+            $this->assertEquals(8, Menu::count());
+        });
+    }
+
+    public function testDeleteMenu()
+    {
+        $this->delete('admin/auth/menu/8');
+        $this->assertEquals(7, Menu::count());
+    }
+
+    public function testEditMenu()
+    {
+        $this->browse(function (Browser $browser) {
+            $browser->visit(new MenuEditPage(1))
+                ->type('title', 'blablabla')
+                ->press(__('admin.submit'))
+                ->waitForLocation(test_admin_path('auth/menu'), 2);
+
+            $this->seeInDatabase(config('admin.database.menu_table'), ['title' => 'blablabla'])
+                ->assertEquals(7, Menu::count());
+        });
+    }
+
+    public function testEditMenuParent()
+    {
+        $this->browse(function (Browser $browser) {
+            $id = 5;
+
+            $browser->visit(new MenuEditPage($id))
+                ->within(new Select2('select[name="parent_id"]'), function ($browser) use ($id) {
+                    $browser->choose($id);
+                })
+                ->press(__('admin.submit'))
+                ->waitForText('500 Internal Server Error', 2);
+        });
+    }
+
+    public function testQuickEditMenu()
+    {
+        $this->browse(function (Browser $browser) {
+            $id = 5;
+
+            $updates = [
+                'title'       => 'balabala',
+                'icon'        => 'fa-list',
+                'parent_id'   => 0,
+                'roles'       => 1,
+                'permissions' => [4, 5, 6],
+            ];
+
+            $browser->visit(new MenuPage())
+                ->within(sprintf('li[data-id="%d"]', $id), function (Browser $browser) {
+                    $browser->click('.tree-quick-edit');
+                })
+                ->whenAvailable('.layui-layer-page', function (Browser $browser) use ($id, $updates) {
+                    $browser->whenElementAvailable(new MenuEditForm($id), function (Browser $browser) use ($updates) {
+                        // 检测表单
+                        $browser->fill($updates);
+                    }, 3)
+                        ->assertSee(__('admin.edit'))
+                        ->click('div')
+                        ->whenElementAvailable(new MultipleSelect2('select[name="roles[]"]'), function (Browser $browser) {
+                            $browser->choose(1);
+                        }, 2)
+                        ->clickLink(__('admin.submit'));
+                }, 3)
+                ->waitForText(__('admin.update_succeeded'), 3)
+                ->waitForLocation(test_admin_path('auth/menu'), 2)
+                ->waitForText('balabala', 2);
+
+            // 检测是否写入数据库
+            $this->assertDatabase($id, $updates);
+        });
+    }
+
+    private function assertDatabase($id, $updates)
+    {
+        $roles = $updates['roles'];
+        $permissions = $updates['permissions'];
+
+        unset($updates['roles'], $updates['permissions']);
+
+        // 检测是否写入数据库
+        return $this
+            ->seeInDatabase(config('admin.database.menu_table'), $updates)
+            ->seeInDatabase(
+                config('admin.database.role_menu_table'),
+                ['role_id' => $roles, 'menu_id' => $id]
+            )
+            ->seeInDatabase(
+                config('admin.database.permission_menu_table'),
+                ['permission_id' => $permissions, 'menu_id' => $id]
+            );
+    }
+}

+ 55 - 55
browser-tests/Browser/Pages/MenuEditPage.php → tests/browser-tests/Browser/Pages/MenuEditPage.php

@@ -1,55 +1,55 @@
-<?php
-
-namespace Tests\Browser\Pages;
-
-use Laravel\Dusk\Browser;
-use Tests\Browser\Components\Form\MenuEditForm;
-
-class MenuEditPage extends Page
-{
-    protected $id;
-
-    public function __construct($id)
-    {
-        $this->id = $id;
-    }
-
-    /**
-     * Get the URL for the page.
-     *
-     * @return string
-     */
-    public function url()
-    {
-        return test_admin_path("auth/menu/{$this->id}/edit");
-    }
-
-    /**
-     * Assert that the browser is on the page.
-     *
-     * @param  \Laravel\Dusk\Browser  $browser
-     * @return void
-     */
-    public function assert(Browser $browser)
-    {
-        $browser->assertSee(__('admin.menu'))
-            ->assertSee(__('admin.edit'))
-            ->assertSee(__('admin.list'))
-            ->assertSee(__('admin.delete'))
-            ->assertSee(__('admin.submit'))
-            ->assertSee(__('admin.reset'))
-            ->assert(new MenuEditForm($this->id));
-    }
-
-    /**
-     * Get the element shortcuts for the page.
-     *
-     * @return array
-     */
-    public function elements()
-    {
-        return [
-            '@form' => 'form[method="POST"]',
-        ];
-    }
-}
+<?php
+
+namespace Tests\Browser\Pages;
+
+use Laravel\Dusk\Browser;
+use Tests\Browser\Components\Form\MenuEditForm;
+
+class MenuEditPage extends Page
+{
+    protected $id;
+
+    public function __construct($id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * Get the URL for the page.
+     *
+     * @return string
+     */
+    public function url()
+    {
+        return test_admin_path("auth/menu/{$this->id}/edit");
+    }
+
+    /**
+     * Assert that the browser is on the page.
+     *
+     * @param  \Laravel\Dusk\Browser  $browser
+     * @return void
+     */
+    public function assert(Browser $browser)
+    {
+        $browser->assertSee(__('admin.menu'))
+            ->assertSee(__('admin.edit'))
+            ->assertSee(__('admin.list'))
+            ->assertSee(__('admin.delete'))
+            ->assertSee(__('admin.submit'))
+            ->assertSee(__('admin.reset'))
+            ->assert(new MenuEditForm($this->id));
+    }
+
+    /**
+     * Get the element shortcuts for the page.
+     *
+     * @return array
+     */
+    public function elements()
+    {
+        return [
+            '@form' => 'form[method="POST"]',
+        ];
+    }
+}

+ 0 - 0
browser-tests/Browser/Pages/MenuPage.php → tests/browser-tests/Browser/Pages/MenuPage.php


+ 0 - 0
browser-tests/Browser/Pages/Page.php → tests/browser-tests/Browser/Pages/Page.php


+ 0 - 0
browser-tests/Browser/console/.gitignore → tests/browser-tests/Browser/console/.gitignore


+ 0 - 0
browser-tests/Browser/screenshots/.gitignore → tests/browser-tests/Browser/screenshots/.gitignore


+ 126 - 126
browser-tests/BrowserExtension.php → tests/browser-tests/BrowserExtension.php

@@ -1,126 +1,126 @@
-<?php
-
-namespace Tests;
-
-use Facebook\WebDriver\Exception\TimeoutException;
-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_int($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_int($callbackOrSeconds)) {
-                    $seconds = $callbackOrSeconds;
-                }
-
-                return $this->whenAvailable($selector, function ($value) use ($callback) {
-                    $callback && $callback($value);
-                }, $seconds);
-            },
-
-            'hasInput' => function ($field) {
-                /* @var \Facebook\WebDriver\Remote\RemoteWebElement $element */
-                $this->resolver->resolveForTyping($field);
-
-                return $this;
-            },
-
-            'wait' => function ($seconds, \Closure $callback = null) {
-                try {
-                    $this->waitUsing($seconds, 200, function () {});
-                } catch (TimeoutException $e) {
-                    $callback && $callback();
-                }
-
-                return $this;
-            },
-
-            'assertHidden' => function ($selector) {
-                $fullSelector = $this->resolver->format($selector);
-
-                PHPUnit::assertTrue(
-                    $this->resolver->findOrFail($selector)->isDisplayed(),
-                    "Element [{$fullSelector}] is visible."
-                );
-
-                return $this;
-            },
-            'assert' => function (Component $component) {
-                return $this->with($component, function () {});
-            },
-        ];
-
-        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;
-            }
-        };
-    }
-}
+<?php
+
+namespace Tests;
+
+use Facebook\WebDriver\Exception\TimeoutException;
+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_int($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_int($callbackOrSeconds)) {
+                    $seconds = $callbackOrSeconds;
+                }
+
+                return $this->whenAvailable($selector, function ($value) use ($callback) {
+                    $callback && $callback($value);
+                }, $seconds);
+            },
+
+            'hasInput' => function ($field) {
+                /* @var \Facebook\WebDriver\Remote\RemoteWebElement $element */
+                $this->resolver->resolveForTyping($field);
+
+                return $this;
+            },
+
+            'wait' => function ($seconds, \Closure $callback = null) {
+                try {
+                    $this->waitUsing($seconds, 200, function () {});
+                } catch (TimeoutException $e) {
+                    $callback && $callback();
+                }
+
+                return $this;
+            },
+
+            'assertHidden' => function ($selector) {
+                $fullSelector = $this->resolver->format($selector);
+
+                PHPUnit::assertTrue(
+                    $this->resolver->findOrFail($selector)->isDisplayed(),
+                    "Element [{$fullSelector}] is visible."
+                );
+
+                return $this;
+            },
+            'assert' => function (Component $component) {
+                return $this->with($component, function () {});
+            },
+        ];
+
+        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;
+            }
+        };
+    }
+}

+ 0 - 0
browser-tests/ChromeProcess.php → tests/browser-tests/ChromeProcess.php


+ 0 - 0
browser-tests/Controllers/DropdownController.php → tests/browser-tests/Controllers/DropdownController.php


+ 0 - 0
browser-tests/Controllers/ReportController.php → tests/browser-tests/Controllers/ReportController.php


+ 0 - 0
browser-tests/Controllers/UserController.php → tests/browser-tests/Controllers/UserController.php


+ 113 - 113
browser-tests/CreatesApplication.php → tests/browser-tests/CreatesApplication.php

@@ -1,113 +1,113 @@
-<?php
-
-namespace Tests;
-
-use Dcat\Admin\Models\Administrator;
-use Illuminate\Contracts\Console\Kernel;
-use Illuminate\Filesystem\Filesystem;
-use Illuminate\Support\Arr;
-use Illuminate\Support\Facades\Artisan;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Schema;
-
-trait CreatesApplication
-{
-    /**
-     * Creates the application.
-     *
-     * @return \Illuminate\Foundation\Application
-     */
-    public function createApplication()
-    {
-        $app = require __DIR__.'/../bootstrap/app.php';
-
-        $app->make(Kernel::class)->bootstrap();
-
-        return $app;
-    }
-
-
-    protected function boot()
-    {
-        $this->config();
-
-        $this->artisan('admin:publish');
-
-        Schema::defaultStringLength(191);
-
-        $this->artisan('admin:install');
-
-        $this->migrateTestTables();
-
-        if (file_exists($routes = admin_path('routes.php'))) {
-            require $routes;
-        }
-
-        require __DIR__.'/helpers.php';
-
-        require __DIR__.'/routes.php';
-
-        require __DIR__.'/resources/seeds/factory.php';
-
-        view()->addNamespace('admin-tests', __DIR__.'/resources/views');
-    }
-
-    protected function destory()
-    {
-        (new \CreateAdminTables())->down();
-
-        (new \CreateTestTables())->down();
-
-        DB::select("delete from `migrations` where `migration` = '2016_01_04_173148_create_admin_tables'");
-        DB::select("delete from `migrations` where `migration` = '2016_11_22_093148_create_test_tables'");
-
-        Artisan::call('migrate:rollback');
-    }
-
-    /**
-     * run package database migrations.
-     *
-     * @return void
-     */
-    public function migrateTestTables()
-    {
-        $fileSystem = new Filesystem();
-
-        $fileSystem->requireOnce(__DIR__.'/resources/migrations/2016_11_22_093148_create_test_tables.php');
-
-        (new \CreateTestTables())->up();
-    }
-
-    protected function config()
-    {
-        $adminConfig = require __DIR__.'/resources/config/admin.php';
-
-        $config = $this->app['config'];
-
-        $config->set('database.default', 'mysql');
-        $config->set('database.connections.mysql.host', env('MYSQL_HOST', 'localhost'));
-        $config->set('database.connections.mysql.database', 'laravel_dcat_admin_test');
-        $config->set('database.connections.mysql.username', env('MYSQL_USER', 'root'));
-        $config->set('database.connections.mysql.password', env('MYSQL_PASSWORD', ''));
-        $config->set('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF');
-        $config->set('filesystems', require __DIR__.'/resources/config/filesystems.php');
-        $config->set('admin', $adminConfig);
-        $config->set('app.debug', true);
-
-        foreach (Arr::dot(Arr::get($adminConfig, 'auth'), 'auth.') as $key => $value) {
-            $this->app['config']->set($key, $value);
-        }
-    }
-
-    /**
-     * @return Administrator
-     */
-    protected function getUser()
-    {
-        if ($this->user) {
-            return $this->user;
-        }
-
-        return $this->user = Administrator::first();
-    }
-}
+<?php
+
+namespace Tests;
+
+use Dcat\Admin\Models\Administrator;
+use Illuminate\Contracts\Console\Kernel;
+use Illuminate\Filesystem\Filesystem;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\Artisan;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+trait CreatesApplication
+{
+    /**
+     * Creates the application.
+     *
+     * @return \Illuminate\Foundation\Application
+     */
+    public function createApplication()
+    {
+        $app = require __DIR__.'/../bootstrap/app.php';
+
+        $app->make(Kernel::class)->bootstrap();
+
+        return $app;
+    }
+
+
+    protected function boot()
+    {
+        $this->config();
+
+        $this->artisan('admin:publish');
+
+        Schema::defaultStringLength(191);
+
+        $this->artisan('admin:install');
+
+        $this->migrateTestTables();
+
+        if (file_exists($routes = admin_path('routes.php'))) {
+            require $routes;
+        }
+
+        require __DIR__.'/helpers.php';
+
+        require __DIR__.'/routes.php';
+
+        require __DIR__.'/resources/seeds/factory.php';
+
+        view()->addNamespace('admin-tests', __DIR__.'/resources/views');
+    }
+
+    protected function destory()
+    {
+        (new \CreateAdminTables())->down();
+
+        (new \CreateTestTables())->down();
+
+        DB::select("delete from `migrations` where `migration` = '2016_01_04_173148_create_admin_tables'");
+        DB::select("delete from `migrations` where `migration` = '2016_11_22_093148_create_test_tables'");
+
+        Artisan::call('migrate:rollback');
+    }
+
+    /**
+     * run package database migrations.
+     *
+     * @return void
+     */
+    public function migrateTestTables()
+    {
+        $fileSystem = new Filesystem();
+
+        $fileSystem->requireOnce(__DIR__.'/resources/migrations/2016_11_22_093148_create_test_tables.php');
+
+        (new \CreateTestTables())->up();
+    }
+
+    protected function config()
+    {
+        $adminConfig = require __DIR__.'/resources/config/admin.php';
+
+        $config = $this->app['config'];
+
+        $config->set('database.default', 'mysql');
+        $config->set('database.connections.mysql.host', env('MYSQL_HOST', 'localhost'));
+        $config->set('database.connections.mysql.database', 'laravel_dcat_admin_test');
+        $config->set('database.connections.mysql.username', env('MYSQL_USER', 'root'));
+        $config->set('database.connections.mysql.password', env('MYSQL_PASSWORD', ''));
+        $config->set('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF');
+        $config->set('filesystems', require __DIR__.'/resources/config/filesystems.php');
+        $config->set('admin', $adminConfig);
+        $config->set('app.debug', true);
+
+        foreach (Arr::dot(Arr::get($adminConfig, 'auth'), 'auth.') as $key => $value) {
+            $this->app['config']->set($key, $value);
+        }
+    }
+
+    /**
+     * @return Administrator
+     */
+    protected function getUser()
+    {
+        if ($this->user) {
+            return $this->user;
+        }
+
+        return $this->user = Administrator::first();
+    }
+}

+ 0 - 0
browser-tests/DuskTestCase.php → tests/browser-tests/DuskTestCase.php


+ 89 - 89
browser-tests/InteractsWithDatabase.php → tests/browser-tests/InteractsWithDatabase.php

@@ -1,89 +1,89 @@
-<?php
-
-namespace Tests;
-
-trait InteractsWithDatabase
-{
-    /**
-     * Assert that a given where condition exists in the database.
-     *
-     * @param  string  $table
-     * @param  array  $data
-     * @param  string  $connection
-     * @return $this
-     */
-    protected function seeInDatabase($table, array $data, $connection = null)
-    {
-        $database = $this->app->make('db');
-
-        $connection = $connection ?: $database->getDefaultConnection();
-
-        $count = $database->connection($connection)->table($table)->where($data)->count();
-
-        $this->assertGreaterThan(0, $count, sprintf(
-            'Unable to find row in database table [%s] that matched attributes [%s].', $table, json_encode($data)
-        ));
-
-        return $this;
-    }
-
-    /**
-     * Assert that a given where condition does not exist in the database.
-     *
-     * @param  string  $table
-     * @param  array  $data
-     * @param  string  $connection
-     * @return $this
-     */
-    protected function missingFromDatabase($table, array $data, $connection = null)
-    {
-        return $this->notSeeInDatabase($table, $data, $connection);
-    }
-
-    /**
-     * Assert that a given where condition does not exist in the database.
-     *
-     * @param  string  $table
-     * @param  array  $data
-     * @param  string  $connection
-     * @return $this
-     */
-    protected function dontSeeInDatabase($table, array $data, $connection = null)
-    {
-        return $this->notSeeInDatabase($table, $data, $connection);
-    }
-
-    /**
-     * Assert that a given where condition does not exist in the database.
-     *
-     * @param  string  $table
-     * @param  array  $data
-     * @param  string  $connection
-     * @return $this
-     */
-    protected function notSeeInDatabase($table, array $data, $connection = null)
-    {
-        $database = $this->app->make('db');
-
-        $connection = $connection ?: $database->getDefaultConnection();
-
-        $count = $database->connection($connection)->table($table)->where($data)->count();
-
-        $this->assertEquals(0, $count, sprintf(
-            'Found unexpected records in database table [%s] that matched attributes [%s].', $table, json_encode($data)
-        ));
-
-        return $this;
-    }
-
-    /**
-     * Seed a given database connection.
-     *
-     * @param  string  $class
-     * @return void
-     */
-    public function seed($class = 'DatabaseSeeder')
-    {
-        $this->artisan('db:seed', ['--class' => $class]);
-    }
-}
+<?php
+
+namespace Tests;
+
+trait InteractsWithDatabase
+{
+    /**
+     * Assert that a given where condition exists in the database.
+     *
+     * @param  string  $table
+     * @param  array  $data
+     * @param  string  $connection
+     * @return $this
+     */
+    protected function seeInDatabase($table, array $data, $connection = null)
+    {
+        $database = $this->app->make('db');
+
+        $connection = $connection ?: $database->getDefaultConnection();
+
+        $count = $database->connection($connection)->table($table)->where($data)->count();
+
+        $this->assertGreaterThan(0, $count, sprintf(
+            'Unable to find row in database table [%s] that matched attributes [%s].', $table, json_encode($data)
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Assert that a given where condition does not exist in the database.
+     *
+     * @param  string  $table
+     * @param  array  $data
+     * @param  string  $connection
+     * @return $this
+     */
+    protected function missingFromDatabase($table, array $data, $connection = null)
+    {
+        return $this->notSeeInDatabase($table, $data, $connection);
+    }
+
+    /**
+     * Assert that a given where condition does not exist in the database.
+     *
+     * @param  string  $table
+     * @param  array  $data
+     * @param  string  $connection
+     * @return $this
+     */
+    protected function dontSeeInDatabase($table, array $data, $connection = null)
+    {
+        return $this->notSeeInDatabase($table, $data, $connection);
+    }
+
+    /**
+     * Assert that a given where condition does not exist in the database.
+     *
+     * @param  string  $table
+     * @param  array  $data
+     * @param  string  $connection
+     * @return $this
+     */
+    protected function notSeeInDatabase($table, array $data, $connection = null)
+    {
+        $database = $this->app->make('db');
+
+        $connection = $connection ?: $database->getDefaultConnection();
+
+        $count = $database->connection($connection)->table($table)->where($data)->count();
+
+        $this->assertEquals(0, $count, sprintf(
+            'Found unexpected records in database table [%s] that matched attributes [%s].', $table, json_encode($data)
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Seed a given database connection.
+     *
+     * @param  string  $class
+     * @return void
+     */
+    public function seed($class = 'DatabaseSeeder')
+    {
+        $this->artisan('db:seed', ['--class' => $class]);
+    }
+}

+ 0 - 0
browser-tests/Models/File.php → tests/browser-tests/Models/File.php


+ 0 - 0
browser-tests/Models/Image.php → tests/browser-tests/Models/Image.php


+ 0 - 0
browser-tests/Models/MultipleImage.php → tests/browser-tests/Models/MultipleImage.php


+ 0 - 0
browser-tests/Models/Profile.php → tests/browser-tests/Models/Profile.php


+ 0 - 0
browser-tests/Models/Tag.php → tests/browser-tests/Models/Tag.php


+ 0 - 0
browser-tests/Models/Tree.php → tests/browser-tests/Models/Tree.php


+ 0 - 0
browser-tests/Models/User.php → tests/browser-tests/Models/User.php


+ 0 - 0
browser-tests/Repositories/Report.php → tests/browser-tests/Repositories/Report.php


+ 0 - 0
browser-tests/Repositories/User.php → tests/browser-tests/Repositories/User.php


+ 7 - 7
browser-tests/TestCase.php → tests/browser-tests/TestCase.php

@@ -1,7 +1,7 @@
-<?php
-
-namespace Tests;
-
-abstract class TestCase extends DuskTestCase
-{
-}
+<?php
+
+namespace Tests;
+
+abstract class TestCase extends DuskTestCase
+{
+}

+ 12 - 12
browser-tests/helpers.php → tests/browser-tests/helpers.php

@@ -1,12 +1,12 @@
-<?php
-
-if (! function_exists('test_admin_path')) {
-    function test_admin_path($path)
-    {
-        if (is_object($path)) {
-            return $path;
-        }
-
-        return admin_base_path($path);
-    }
-}
+<?php
+
+if (! function_exists('test_admin_path')) {
+    function test_admin_path($path)
+    {
+        if (is_object($path)) {
+            return $path;
+        }
+
+        return admin_base_path($path);
+    }
+}

+ 0 - 0
browser-tests/resources/assets/test.jpg → tests/browser-tests/resources/assets/test.jpg


+ 0 - 0
browser-tests/resources/config/admin.php → tests/browser-tests/resources/config/admin.php


+ 0 - 0
browser-tests/resources/config/filesystems.php → tests/browser-tests/resources/config/filesystems.php


+ 0 - 0
browser-tests/resources/drivers/chromedriver-linux → tests/browser-tests/resources/drivers/chromedriver-linux


+ 0 - 0
browser-tests/resources/drivers/chromedriver-mac → tests/browser-tests/resources/drivers/chromedriver-mac


+ 0 - 0
browser-tests/resources/drivers/chromedriver-win.exe → tests/browser-tests/resources/drivers/chromedriver-win.exe


+ 0 - 0
browser-tests/resources/lang/en/global.php → tests/browser-tests/resources/lang/en/global.php


+ 0 - 0
browser-tests/resources/lang/en/user.php → tests/browser-tests/resources/lang/en/user.php


+ 0 - 0
browser-tests/resources/migrations/2016_11_22_093148_create_test_tables.php → tests/browser-tests/resources/migrations/2016_11_22_093148_create_test_tables.php


+ 0 - 0
browser-tests/resources/seeds/UserTableSeeder.php → tests/browser-tests/resources/seeds/UserTableSeeder.php


+ 0 - 0
browser-tests/resources/seeds/factory.php → tests/browser-tests/resources/seeds/factory.php


+ 0 - 0
browser-tests/resources/views/test.blade.php → tests/browser-tests/resources/views/test.blade.php


+ 0 - 0
browser-tests/routes.php → tests/browser-tests/routes.php