Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

357 linhas
9.4 KiB

  1. import 'cypress-file-upload';
  2. import '@testing-library/cypress/add-commands';
  3. // ***********************************************
  4. // This example commands.js shows you how to
  5. // create various custom commands and overwrite
  6. // existing commands.
  7. //
  8. // For more comprehensive examples of custom
  9. // commands please read more here:
  10. // https://on.cypress.io/custom-commands
  11. // ***********************************************
  12. //
  13. //
  14. // -- This is a parent command --
  15. // Cypress.Commands.add("login", (email, password) => { ... });
  16. //
  17. //
  18. // -- This is a child command --
  19. // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... });
  20. //
  21. //
  22. // -- This is a dual command --
  23. // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... });
  24. //
  25. //
  26. // -- This is will overwrite an existing command --
  27. // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... });
  28. Cypress.Commands.add('login', (email, password) => {
  29. if (!email) {
  30. email = 'Administrator';
  31. }
  32. if (!password) {
  33. password = Cypress.config('adminPassword');
  34. }
  35. cy.request({
  36. url: '/api/method/login',
  37. method: 'POST',
  38. body: {
  39. usr: email,
  40. pwd: password
  41. }
  42. });
  43. });
  44. Cypress.Commands.add('call', (method, args) => {
  45. return cy
  46. .window()
  47. .its('frappe.csrf_token')
  48. .then(csrf_token => {
  49. return cy
  50. .request({
  51. url: `/api/method/${method}`,
  52. method: 'POST',
  53. body: args,
  54. headers: {
  55. Accept: 'application/json',
  56. 'Content-Type': 'application/json',
  57. 'X-Frappe-CSRF-Token': csrf_token
  58. }
  59. })
  60. .then(res => {
  61. expect(res.status).eq(200);
  62. return res.body;
  63. });
  64. });
  65. });
  66. Cypress.Commands.add('get_list', (doctype, fields = [], filters = []) => {
  67. filters = JSON.stringify(filters);
  68. fields = JSON.stringify(fields);
  69. let url = `/api/resource/${doctype}?fields=${fields}&filters=${filters}`;
  70. return cy
  71. .window()
  72. .its('frappe.csrf_token')
  73. .then(csrf_token => {
  74. return cy
  75. .request({
  76. method: 'GET',
  77. url,
  78. headers: {
  79. Accept: 'application/json',
  80. 'X-Frappe-CSRF-Token': csrf_token
  81. }
  82. })
  83. .then(res => {
  84. expect(res.status).eq(200);
  85. return res.body;
  86. });
  87. });
  88. });
  89. Cypress.Commands.add('get_doc', (doctype, name) => {
  90. return cy
  91. .window()
  92. .its('frappe.csrf_token')
  93. .then(csrf_token => {
  94. return cy
  95. .request({
  96. method: 'GET',
  97. url: `/api/resource/${doctype}/${name}`,
  98. headers: {
  99. Accept: 'application/json',
  100. 'X-Frappe-CSRF-Token': csrf_token
  101. }
  102. })
  103. .then(res => {
  104. expect(res.status).eq(200);
  105. return res.body;
  106. });
  107. });
  108. });
  109. Cypress.Commands.add('insert_doc', (doctype, args, ignore_duplicate) => {
  110. return cy
  111. .window()
  112. .its('frappe.csrf_token')
  113. .then(csrf_token => {
  114. return cy
  115. .request({
  116. method: 'POST',
  117. url: `/api/resource/${doctype}`,
  118. body: args,
  119. headers: {
  120. Accept: 'application/json',
  121. 'Content-Type': 'application/json',
  122. 'X-Frappe-CSRF-Token': csrf_token
  123. },
  124. failOnStatusCode: !ignore_duplicate
  125. })
  126. .then(res => {
  127. let status_codes = [200];
  128. if (ignore_duplicate) {
  129. status_codes.push(409);
  130. }
  131. expect(res.status).to.be.oneOf(status_codes);
  132. return res.body;
  133. });
  134. });
  135. });
  136. Cypress.Commands.add('remove_doc', (doctype, name) => {
  137. return cy
  138. .window()
  139. .its('frappe.csrf_token')
  140. .then(csrf_token => {
  141. return cy
  142. .request({
  143. method: 'DELETE',
  144. url: `/api/resource/${doctype}/${name}`,
  145. headers: {
  146. Accept: 'application/json',
  147. 'X-Frappe-CSRF-Token': csrf_token
  148. }
  149. })
  150. .then(res => {
  151. expect(res.status).eq(202);
  152. return res.body;
  153. });
  154. });
  155. });
  156. Cypress.Commands.add('create_records', doc => {
  157. return cy
  158. .call('frappe.tests.ui_test_helpers.create_if_not_exists', {doc})
  159. .then(r => r.message);
  160. });
  161. Cypress.Commands.add('set_value', (doctype, name, obj) => {
  162. return cy.call('frappe.client.set_value', {
  163. doctype,
  164. name,
  165. fieldname: obj
  166. });
  167. });
  168. Cypress.Commands.add('fill_field', (fieldname, value, fieldtype = 'Data') => {
  169. cy.get_field(fieldname, fieldtype).as('input');
  170. if (['Date', 'Time', 'Datetime'].includes(fieldtype)) {
  171. cy.get('@input').click().wait(200);
  172. cy.get('.datepickers-container .datepicker.active').should('exist');
  173. }
  174. if (fieldtype === 'Time') {
  175. cy.get('@input').clear().wait(200);
  176. }
  177. if (fieldtype === 'Select') {
  178. cy.get('@input').select(value);
  179. } else {
  180. cy.get('@input').type(value, {waitForAnimations: false, force: true});
  181. }
  182. return cy.get('@input');
  183. });
  184. Cypress.Commands.add('get_field', (fieldname, fieldtype = 'Data') => {
  185. let selector = `[data-fieldname="${fieldname}"] input:visible`;
  186. if (fieldtype === 'Text Editor') {
  187. selector = `[data-fieldname="${fieldname}"] .ql-editor[contenteditable=true]:visible`;
  188. }
  189. if (fieldtype === 'Code') {
  190. selector = `[data-fieldname="${fieldname}"] .ace_text-input`;
  191. }
  192. return cy.get(selector).first();
  193. });
  194. Cypress.Commands.add('fill_table_field', (tablefieldname, row_idx, fieldname, value, fieldtype = 'Data') => {
  195. cy.get_table_field(tablefieldname, row_idx, fieldname, fieldtype).as('input');
  196. if (['Date', 'Time', 'Datetime'].includes(fieldtype)) {
  197. cy.get('@input').click().wait(200);
  198. cy.get('.datepickers-container .datepicker.active').should('exist');
  199. }
  200. if (fieldtype === 'Time') {
  201. cy.get('@input').clear().wait(200);
  202. }
  203. if (fieldtype === 'Select') {
  204. cy.get('@input').select(value);
  205. } else {
  206. cy.get('@input').type(value, {waitForAnimations: false, force: true});
  207. }
  208. return cy.get('@input');
  209. });
  210. Cypress.Commands.add('get_table_field', (tablefieldname, row_idx, fieldname, fieldtype = 'Data') => {
  211. let selector = `.frappe-control[data-fieldname="${tablefieldname}"]`;
  212. selector += ` [data-idx="${row_idx}"]`;
  213. selector += ` .form-in-grid`;
  214. if (fieldtype === 'Text Editor') {
  215. selector += ` [data-fieldname="${fieldname}"] .ql-editor[contenteditable=true]`;
  216. } else if (fieldtype === 'Code') {
  217. selector += ` [data-fieldname="${fieldname}"] .ace_text-input`;
  218. } else {
  219. selector += ` .form-control[data-fieldname="${fieldname}"]`;
  220. }
  221. return cy.get(selector);
  222. });
  223. Cypress.Commands.add('awesomebar', text => {
  224. cy.get('#navbar-search').type(`${text}{downarrow}{enter}`, {delay: 100});
  225. });
  226. Cypress.Commands.add('new_form', doctype => {
  227. let dt_in_route = doctype.toLowerCase().replace(/ /g, '-');
  228. cy.visit(`/app/${dt_in_route}/new`);
  229. cy.get('body').should('have.attr', 'data-route', `Form/${doctype}/new-${dt_in_route}-1`);
  230. cy.get('body').should('have.attr', 'data-ajax-state', 'complete');
  231. });
  232. Cypress.Commands.add('go_to_list', doctype => {
  233. let dt_in_route = doctype.toLowerCase().replace(/ /g, '-');
  234. cy.visit(`/app/${dt_in_route}`);
  235. });
  236. Cypress.Commands.add('clear_cache', () => {
  237. cy.window()
  238. .its('frappe')
  239. .then(frappe => {
  240. frappe.ui.toolbar.clear_cache();
  241. });
  242. });
  243. Cypress.Commands.add('dialog', opts => {
  244. return cy.window().then(win => {
  245. var d = new win.frappe.ui.Dialog(opts);
  246. d.show();
  247. return d;
  248. });
  249. });
  250. Cypress.Commands.add('get_open_dialog', () => {
  251. return cy.get('.modal:visible').last();
  252. });
  253. Cypress.Commands.add('hide_dialog', () => {
  254. cy.wait(300);
  255. cy.get_open_dialog().find('.btn-modal-close').click();
  256. cy.get('.modal:visible').should('not.exist');
  257. });
  258. Cypress.Commands.add('insert_doc', (doctype, args, ignore_duplicate) => {
  259. return cy
  260. .window()
  261. .its('frappe.csrf_token')
  262. .then(csrf_token => {
  263. return cy
  264. .request({
  265. method: 'POST',
  266. url: `/api/resource/${doctype}`,
  267. body: args,
  268. headers: {
  269. Accept: 'application/json',
  270. 'Content-Type': 'application/json',
  271. 'X-Frappe-CSRF-Token': csrf_token
  272. },
  273. failOnStatusCode: !ignore_duplicate
  274. })
  275. .then(res => {
  276. let status_codes = [200];
  277. if (ignore_duplicate) {
  278. status_codes.push(409);
  279. }
  280. expect(res.status).to.be.oneOf(status_codes);
  281. return res.body.data;
  282. });
  283. });
  284. });
  285. Cypress.Commands.add('add_filter', () => {
  286. cy.get('.filter-section .filter-button').click();
  287. cy.wait(300);
  288. cy.get('.filter-popover').should('exist');
  289. });
  290. Cypress.Commands.add('clear_filters', () => {
  291. cy.intercept({
  292. method: 'POST',
  293. url: 'api/method/frappe.model.utils.user_settings.save'
  294. }).as('filter-saved');
  295. cy.get('.filter-section .filter-button').click({force: true});
  296. cy.wait(300);
  297. cy.get('.filter-popover').should('exist');
  298. cy.get('.filter-popover').find('.clear-filters').click();
  299. cy.get('.filter-section .filter-button').click();
  300. cy.window().its('cur_list').then(cur_list => {
  301. cur_list && cur_list.filter_area && cur_list.filter_area.clear();
  302. });
  303. cy.wait('@filter-saved');
  304. });
  305. Cypress.Commands.add('click_modal_primary_button', (btn_name) => {
  306. cy.get('.modal-footer > .standard-actions > .btn-primary').contains(btn_name).trigger('click', {force: true});
  307. });
  308. Cypress.Commands.add('click_sidebar_button', (btn_name) => {
  309. cy.get('.list-group-by-fields .list-link > a').contains(btn_name).click({force: true});
  310. });
  311. Cypress.Commands.add('click_listview_row_item', (row_no) => {
  312. cy.get('.list-row > .level-left > .list-subject > .bold > .ellipsis').eq(row_no).click({force: true});
  313. });
  314. Cypress.Commands.add('click_filter_button', () => {
  315. cy.get('.filter-selector > .btn').click();
  316. });
  317. Cypress.Commands.add('click_listview_primary_button', (btn_name) => {
  318. cy.get('.primary-action').contains(btn_name).click({force: true});
  319. });
  320. Cypress.Commands.add('click_timeline_action_btn', (btn_name) => {
  321. cy.get('.timeline-content > .timeline-message-box > .justify-between > .actions > .btn').contains(btn_name).click();
  322. });