HasMany.php 5.3 KB

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