HasMany.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. namespace Tests\Browser\Components\Form\Field;
  3. use Dcat\Admin\Form\NestedForm;
  4. use Laravel\Dusk\Browser;
  5. use Tests\Browser\Components\Component;
  6. use Tests\PHPUnit;
  7. class HasMany extends Component
  8. {
  9. protected $relation;
  10. public function __construct($relation = null)
  11. {
  12. $this->relation = $relation;
  13. }
  14. /**
  15. * 获取组件的 root selector.
  16. *
  17. * @return string
  18. */
  19. public function selector()
  20. {
  21. return '@container';
  22. }
  23. /**
  24. * 浏览器包含组件的断言
  25. *
  26. * @param Browser $browser
  27. * @return void
  28. */
  29. public function assert(Browser $browser)
  30. {
  31. $browser->assertVisible('@container')
  32. ->assertVisible('@add')
  33. ->assertVisible('@forms');
  34. }
  35. /**
  36. * 读取组件的元素快捷方式.
  37. *
  38. * @return array
  39. */
  40. public function elements()
  41. {
  42. return [
  43. '@container' => '.has-many-'.$this->relation,
  44. '@add' => ".{$this->relation}-add",
  45. '@remove' => ".{$this->relation}-remove",
  46. '@forms' => ".has-many-{$this->relation}-forms",
  47. '@group' => ".has-many-{$this->relation}-forms .has-many-{$this->relation}-form",
  48. ];
  49. }
  50. /**
  51. * 点击添加按钮.
  52. *
  53. * @param Browser $browser
  54. * @return int
  55. */
  56. public function add(Browser $browser)
  57. {
  58. $browser->script(
  59. <<<JS
  60. $('{$this->formatSelector($browser, '@add')}').click();
  61. JS
  62. );
  63. // 获取最后一个添加的表单组
  64. $index = $this->getLastFormGroupIndex($browser);
  65. $browser->scrollToBottom();
  66. // 验证表单组是否存在
  67. $this->withFormGroup($browser, $index);
  68. return $index;
  69. }
  70. /**
  71. * 获取最后一组新增的表单索引.
  72. *
  73. * @param Browser $browser
  74. * @return int|null
  75. */
  76. public function getLastFormGroupIndex(Browser $browser)
  77. {
  78. // 获取添加的表单个数
  79. $length = $browser->script(
  80. <<<JS
  81. return $('{$this->formatSelector($browser, '@group')}').length;
  82. JS
  83. );
  84. return $length[0] ?? 0;
  85. }
  86. /**
  87. * @param Browser $browser
  88. * @param \Closure $callback
  89. * @return Browser
  90. */
  91. public function withLastFormGroup(Browser $browser, \Closure $callback = null)
  92. {
  93. return $this->withFormGroup($browser, $this->getLastFormGroupIndex($browser), $callback);
  94. }
  95. /**
  96. * 检测表单组.
  97. *
  98. * @param Browser $browser
  99. * @param \Closure $callback
  100. * @return Browser
  101. */
  102. public function withFormGroup(Browser $browser, $index, ?\Closure $callback = null)
  103. {
  104. // 添加的表单组容器选择器
  105. $groupSelector = $this->formatGroupSelector($browser, $index);
  106. $browser->assertVisible($groupSelector);
  107. $browser->assertVisible("{$groupSelector} {$this->formatSelectorWithoutPrefix($browser, '@remove')}");
  108. return $callback ? $browser->extend($groupSelector, $callback) : $browser;
  109. }
  110. /**
  111. * @param Browser $browser
  112. * @param int $index
  113. * @return string
  114. */
  115. protected function formatGroupSelector(Browser $browser, $index)
  116. {
  117. return "{$this->formatSelectorWithoutPrefix($browser, '@group')}:nth-of-type({$index})";
  118. }
  119. /**
  120. * 移除表单.
  121. *
  122. * @param Browser $browser
  123. * @param int $index
  124. * @return Browser
  125. */
  126. public function remove(Browser $browser, $index)
  127. {
  128. $this->withFormGroup($browser, $index, function (Browser $browser) {
  129. $browser->script(
  130. <<<JS
  131. $('{$this->formatSelector($browser, $this->elements()['@remove'])}').click();
  132. JS
  133. );
  134. });
  135. return $browser->assertHidden($this->formatGroupSelector($browser, $index));
  136. }
  137. /**
  138. * 移除最后一个表单.
  139. *
  140. * @param Browser $browser
  141. * @return Browser
  142. */
  143. public function removeLast(Browser $browser)
  144. {
  145. return $this->remove($browser, $this->getLastFormGroupIndex($browser));
  146. }
  147. /**
  148. * 获取hasMany内表单字段值.
  149. *
  150. * @param Browser $browser
  151. * @param string $field
  152. * @param string $value
  153. * @return string|null
  154. */
  155. public function assertFormGroupInputValue(Browser $browser, $field, $value, $id = null)
  156. {
  157. $input = $browser->script(
  158. <<<JS
  159. return $('{$this->getFieldSelector($browser, $field, $id)}').val();
  160. JS
  161. )[0] ?? null;
  162. PHPUnit::assertEquals($input, $value);
  163. }
  164. /**
  165. * 填充字段数据.
  166. *
  167. * @param \Laravel\Dusk\Browser $browser
  168. * @param $field
  169. * @param $value
  170. * @param null $id
  171. */
  172. public function fillFieldValue(Browser $browser, $field, $value, $id = null)
  173. {
  174. $browser->script(
  175. <<<JS
  176. $('{$this->getFieldSelector($browser, $field, $id)}').val('$value');
  177. JS
  178. );
  179. }
  180. /**
  181. * 获取元素选择器.
  182. *
  183. * @param $field
  184. * @param null $id
  185. * @return array|string
  186. */
  187. public function getFieldSelector(Browser $browser, $field, $id = null)
  188. {
  189. return $browser->resolver->format(
  190. (new NestedForm($this->relation, $id))
  191. ->text($field)
  192. ->getElementClassSelector()
  193. );
  194. }
  195. }