HasMany.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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' => '.add',
  45. '@remove' => '.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. *
  55. * @return int
  56. */
  57. public function add(Browser $browser)
  58. {
  59. $browser->script(
  60. <<<JS
  61. $('{$this->formatSelector($browser, '@add')}').click();
  62. JS
  63. );
  64. // 获取最后一个添加的表单组
  65. $index = $this->getLastFormGroupIndex($browser);
  66. $browser->scrollToBottom();
  67. // 验证表单组是否存在
  68. $this->withFormGroup($browser, $index);
  69. return $index;
  70. }
  71. /**
  72. * 获取最后一组新增的表单索引.
  73. *
  74. * @param Browser $browser
  75. *
  76. * @return int|null
  77. */
  78. public function getLastFormGroupIndex(Browser $browser)
  79. {
  80. // 获取添加的表单个数
  81. $length = $browser->script(
  82. <<<JS
  83. return $('{$this->formatSelector($browser, '@group')}').length;
  84. JS
  85. );
  86. return $length[0] ?? 0;
  87. }
  88. /**
  89. * @param Browser $browser
  90. * @param \Closure $callback
  91. *
  92. * @return Browser
  93. */
  94. public function withLastFormGroup(Browser $browser, \Closure $callback = null)
  95. {
  96. return $this->withFormGroup($browser, $this->getLastFormGroupIndex($browser), $callback);
  97. }
  98. /**
  99. * 检测表单组.
  100. *
  101. * @param Browser $browser
  102. * @param \Closure $callback
  103. *
  104. * @return Browser
  105. */
  106. public function withFormGroup(Browser $browser, $index, ?\Closure $callback = null)
  107. {
  108. // 添加的表单组容器选择器
  109. $groupSelector = $this->formatGroupSelector($browser, $index);
  110. $browser->assertVisible($groupSelector);
  111. $browser->assertVisible("{$groupSelector} {$this->formatSelectorWithoutPrefix($browser, '@remove')}");
  112. return $callback ? $browser->extend($groupSelector, $callback) : $browser;
  113. }
  114. /**
  115. * @param Browser $browser
  116. * @param int $index
  117. *
  118. * @return string
  119. */
  120. protected function formatGroupSelector(Browser $browser, $index)
  121. {
  122. return "{$this->formatSelectorWithoutPrefix($browser, '@group')}:nth-of-type({$index})";
  123. }
  124. /**
  125. * 移除表单.
  126. *
  127. * @param Browser $browser
  128. * @param int $index
  129. *
  130. * @return Browser
  131. */
  132. public function remove(Browser $browser, $index)
  133. {
  134. $this->withFormGroup($browser, $index, function (Browser $browser) {
  135. $browser->script(
  136. <<<JS
  137. $('{$this->formatSelector($browser, $this->elements()['@remove'])}').click();
  138. JS
  139. );
  140. });
  141. return $browser->assertHidden($this->formatGroupSelector($browser, $index));
  142. }
  143. /**
  144. * 移除最后一个表单.
  145. *
  146. * @param Browser $browser
  147. *
  148. * @return Browser
  149. */
  150. public function removeLast(Browser $browser)
  151. {
  152. return $this->remove($browser, $this->getLastFormGroupIndex($browser));
  153. }
  154. /**
  155. * 获取hasMany内表单字段值.
  156. *
  157. * @param Browser $browser
  158. * @param string $field
  159. * @param string $value
  160. *
  161. * @return string|null
  162. */
  163. public function assertFormGroupInputValue(Browser $browser, $field, $value, $id = null)
  164. {
  165. $input = $browser->script(
  166. <<<JS
  167. return $('{$this->getFieldSelector($browser, $field, $id)}').val();
  168. JS
  169. )[0] ?? null;
  170. PHPUnit::assertEquals($input, $value);
  171. }
  172. /**
  173. * 填充字段数据.
  174. *
  175. * @param \Laravel\Dusk\Browser $browser
  176. * @param $field
  177. * @param $value
  178. * @param null $id
  179. */
  180. public function fillFieldValue(Browser $browser, $field, $value, $id = null)
  181. {
  182. $browser->script(
  183. <<<JS
  184. $('{$this->getFieldSelector($browser, $field, $id)}').val('$value');
  185. JS
  186. );
  187. }
  188. /**
  189. * 获取元素选择器.
  190. *
  191. * @param $field
  192. * @param null $id
  193. *
  194. * @return array|string
  195. */
  196. public function getFieldSelector(Browser $browser, $field, $id = null)
  197. {
  198. return $browser->resolver->format(
  199. (new NestedForm($this->relation, $id))
  200. ->text($field)
  201. ->getElementClassSelector()
  202. );
  203. }
  204. }