How to use closeStudioAssertionsMenu method in Cypress

Best JavaScript code snippet using cypress

studio-recorder.spec.js

Source:studio-recorder.spec.js Github

copy

Full Screen

1import sinon from 'sinon'2import $ from 'jquery'3import driver from '@packages/driver'4import { eventManager } from '../event-manager'5import { dom } from '../dom'6import { StudioRecorder, studioRecorder } from './studio-recorder'7const createEvent = (props) => {8 return {9 isTrusted: true,10 type: 'click',11 preventDefault: sinon.stub(),12 stopPropagation: sinon.stub(),13 ...props,14 }15}16describe('StudioRecorder', () => {17 const cyVisitStub = sinon.stub()18 const getSelectorStub = sinon.stub().returns('.selector')19 const setOnlyTestIdStub = sinon.stub()20 const setOnlySuiteIdStub = sinon.stub()21 let instance22 beforeEach(() => {23 instance = new StudioRecorder()24 sinon.stub(instance, 'attachListeners')25 sinon.stub(instance, 'removeListeners')26 sinon.stub(dom, 'closeStudioAssertionsMenu')27 sinon.stub(dom, 'openStudioAssertionsMenu')28 driver.$ = $29 sinon.stub(eventManager, 'emit')30 sinon.stub(eventManager, 'getCypress').returns({31 cy: {32 visit: cyVisitStub,33 },34 SelectorPlayground: {35 getSelector: getSelectorStub,36 },37 runner: {38 setOnlyTestId: setOnlyTestIdStub,39 setOnlySuiteId: setOnlySuiteIdStub,40 },41 env: () => null,42 })43 })44 afterEach(() => {45 sinon.restore()46 })47 it('exports a singleton by named export', () => {48 expect(studioRecorder).to.be.instanceOf(StudioRecorder)49 })50 context('#startLoading', () => {51 it('sets isLoading, isOpen to true', () => {52 instance.startLoading()53 expect(instance.isLoading).to.be.true54 expect(instance.isOpen).to.be.true55 })56 })57 context('#setTestId', () => {58 it('sets testId to id and hasRunnableId to true', () => {59 instance.setTestId('r2')60 expect(instance.testId).to.equal('r2')61 expect(instance.hasRunnableId).to.be.true62 expect(instance.state.testId).to.equal('r2')63 })64 it('does not clear suite id', () => {65 instance.suiteId = 'r1'66 instance.setTestId('r2')67 expect(instance.suiteId).to.equal('r1')68 })69 })70 context('#setSuiteId', () => {71 it('sets suiteId to id and hasRunnableId to true', () => {72 instance.setSuiteId('r1')73 expect(instance.suiteId).to.equal('r1')74 expect(instance.hasRunnableId).to.be.true75 expect(instance.state.suiteId).to.equal('r1')76 })77 it('clears test id', () => {78 instance.testId = 'r2'79 instance.setSuiteId('r1')80 expect(instance.testId).to.be.null81 })82 })83 context('#initialize', () => {84 const config = {85 spec: {86 absolute: '/path/to/spec.js',87 },88 }89 it('restores state, grabs config info, and initializes driver when extending test', () => {90 const state = {91 studio: {92 testId: 'r2',93 suiteId: null,94 url: null,95 },96 }97 instance.initialize(config, state)98 expect(instance.testId).to.equal('r2')99 expect(instance.absoluteFile).to.equal('/path/to/spec.js')100 expect(instance.isLoading).to.be.true101 expect(setOnlyTestIdStub).to.be.calledWith('r2')102 })103 it('restores state, grabs config info, and initializes driver when adding to suite', () => {104 const state = {105 studio: {106 testId: null,107 suiteId: 'r1',108 url: 'https://example.com',109 },110 }111 instance.initialize(config, state)112 expect(instance.suiteId).to.equal('r1')113 expect(instance.url).to.equal('https://example.com')114 expect(instance.absoluteFile).to.equal('/path/to/spec.js')115 expect(instance.isLoading).to.be.true116 expect(setOnlySuiteIdStub).to.be.calledWith('r1')117 })118 it('grabs config info and initializes driver when state already exists while extending test', () => {119 instance.setTestId('r2')120 instance.initialize(config, {})121 expect(instance.absoluteFile).to.equal('/path/to/spec.js')122 expect(instance.isLoading).to.be.true123 expect(setOnlyTestIdStub).to.be.calledWith('r2')124 })125 it('grabs config info and initializes driver when state already exists while adding to suite', () => {126 instance.setSuiteId('r1')127 instance.initialize(config, {})128 expect(instance.absoluteFile).to.equal('/path/to/spec.js')129 expect(instance.isLoading).to.be.true130 expect(setOnlySuiteIdStub).to.be.calledWith('r1')131 })132 })133 context('#interceptTest', () => {134 it('grabs test data when extending test', () => {135 const invocationDetails = {136 absoluteFile: '/path/to/spec',137 line: 20,138 column: 5,139 }140 const test = {141 id: 'r2',142 title: 'my test',143 invocationDetails,144 }145 instance.setTestId('r2')146 instance.interceptTest(test)147 expect(instance.fileDetails).to.equal(invocationDetails)148 expect(instance.runnableTitle).to.equal('my test')149 })150 it('grabs test and suite data when adding to suite', () => {151 const invocationDetails = {152 absoluteFile: '/path/to/spec',153 line: 20,154 column: 5,155 }156 const suite = {157 id: 'r2',158 title: 'my suite',159 }160 const test = {161 id: 'r3',162 title: 'my test',163 invocationDetails,164 parent: suite,165 }166 instance.setSuiteId('r2')167 instance.interceptTest(test)168 expect(instance.testId).to.equal('r3')169 expect(instance.fileDetails).to.equal(invocationDetails)170 expect(instance.runnableTitle).to.equal('my suite')171 })172 it('does not grab parent title when adding to root', () => {173 const root = {174 id: 'r1',175 title: '',176 }177 const test = {178 id: 'r2',179 title: 'my test',180 parent: root,181 }182 instance.setSuiteId('r1')183 instance.interceptTest(test)184 expect(instance.testId).to.equal('r2')185 expect(instance.fileDetails).to.be.null186 expect(instance.runnableTitle).to.be.null187 })188 })189 context('#start', () => {190 beforeEach(() => {191 sinon.stub(instance, 'visitUrl')192 })193 it('sets isActive, isOpen to true and isLoading to false', () => {194 instance.start(null)195 expect(instance.isActive).to.be.true196 expect(instance.isLoading).to.be.false197 expect(instance.isOpen).to.be.true198 })199 it('clears any existing logs', () => {200 instance.logs = ['log 1', 'log 2']201 instance.start(null)202 expect(instance.logs).to.be.empty203 })204 it('visits url if url has been set', () => {205 instance.url = 'cypress.io'206 instance.start(null)207 expect(instance.visitUrl).to.be.called208 })209 it('attaches listeners to the body', () => {210 instance.start('body')211 expect(instance.attachListeners).to.be.calledWith('body')212 })213 })214 context('#stop', () => {215 beforeEach(() => {216 instance.start()217 })218 it('removes listeners', () => {219 instance.stop()220 expect(instance.removeListeners).to.be.called221 })222 it('sets isActive, isLoading to false and isOpen is true', () => {223 instance.stop()224 expect(instance.isActive).to.be.false225 expect(instance.isOpen).to.be.true226 })227 })228 context('#reset', () => {229 beforeEach(() => {230 instance.start()231 })232 it('removes listeners', () => {233 instance.reset()234 expect(instance.removeListeners).to.be.called235 })236 it('sets isActive, isOpen to false', () => {237 instance.reset()238 expect(instance.isActive).to.be.false239 expect(instance.isOpen).to.be.false240 })241 it('clears logs and url', () => {242 instance.reset()243 expect(instance.logs).to.be.empty244 expect(instance.url).to.be.null245 })246 it('does not remove runnable ids', () => {247 instance.testId = 'r2'248 instance.suiteId = 'r1'249 instance.reset()250 expect(instance.hasRunnableId).to.be.true251 })252 })253 context('#cancel', () => {254 beforeEach(() => {255 instance.start()256 })257 it('removes listeners', () => {258 instance.cancel()259 expect(instance.removeListeners).to.be.called260 })261 it('sets isActive, isOpen to false', () => {262 instance.cancel()263 expect(instance.isActive).to.be.false264 expect(instance.isOpen).to.be.false265 })266 it('clears logs and url', () => {267 instance.logs = ['log 1', 'log 2']268 instance.cancel()269 expect(instance.logs).to.be.empty270 expect(instance.url).to.be.null271 })272 it('removes runnable ids', () => {273 instance.testId = 'r2'274 instance.suiteId = 'r1'275 instance.cancel()276 expect(instance.hasRunnableId).to.be.false277 })278 })279 context('#startSave', () => {280 beforeEach(() => {281 instance.start()282 })283 it('shows save modal if suite', () => {284 instance.suiteId = 'r1'285 instance.startSave()286 expect(instance.saveModalIsOpen).to.be.true287 })288 it('skips modal and goes directly to save if test', () => {289 sinon.stub(instance, 'save')290 instance.testId = 'r2'291 instance.startSave()292 expect(instance.save).to.be.called293 })294 })295 context('#save', () => {296 beforeEach(() => {297 instance.start()298 })299 it('closes save modal', () => {300 instance.showSaveModal()301 instance.save()302 expect(instance.saveModalIsOpen).to.be.false303 })304 it('removes listeners', () => {305 instance.save()306 expect(instance.removeListeners).to.be.called307 })308 it('sets isActive to false and isOpen is true', () => {309 instance.save()310 expect(instance.isActive).to.be.false311 expect(instance.isOpen).to.be.true312 })313 it('emits studio:save with relevant test information', () => {314 const fileDetails = {315 absoluteFile: '/path/to/spec.js',316 line: 10,317 column: 4,318 }319 const absoluteFile = '/path/to/spec.js'320 const runnableTitle = 'my test'321 const logs = ['log 1', 'log 2']322 instance.setFileDetails(fileDetails)323 instance.setAbsoluteFile(absoluteFile)324 instance.setRunnableTitle(runnableTitle)325 instance.logs = logs326 instance.testId = 'r2'327 instance.save()328 expect(eventManager.emit).to.be.calledWith('studio:save', {329 fileDetails,330 absoluteFile,331 runnableTitle,332 commands: logs,333 isSuite: false,334 isRoot: false,335 testName: null,336 })337 })338 it('emits studio:save with relevant suite information', () => {339 const fileDetails = {340 absoluteFile: '/path/to/spec.js',341 line: 10,342 column: 4,343 }344 const absoluteFile = '/path/to/spec.js'345 const runnableTitle = 'my suite'346 const logs = ['log 1', 'log 2']347 instance.setFileDetails(fileDetails)348 instance.setAbsoluteFile(absoluteFile)349 instance.setRunnableTitle(runnableTitle)350 instance.logs = logs351 instance.suiteId = 'r2'352 instance.save('new test name')353 expect(eventManager.emit).to.be.calledWith('studio:save', {354 fileDetails,355 absoluteFile,356 runnableTitle,357 commands: logs,358 isSuite: true,359 isRoot: false,360 testName: 'new test name',361 })362 })363 it('emits studio:save with relevant suite information for root suite', () => {364 const absoluteFile = '/path/to/spec.js'365 const logs = ['log 1', 'log 2']366 instance.setAbsoluteFile(absoluteFile)367 instance.logs = logs368 instance.suiteId = 'r1'369 instance.save('new test name')370 expect(eventManager.emit).to.be.calledWith('studio:save', {371 fileDetails: null,372 absoluteFile,373 runnableTitle: null,374 commands: logs,375 isSuite: true,376 isRoot: true,377 testName: 'new test name',378 })379 })380 })381 context('#visitUrl', () => {382 it('visits existing url by default', () => {383 instance.url = 'cypress.io'384 instance.visitUrl()385 expect(cyVisitStub).to.be.calledWith('cypress.io')386 })387 it('visits and sets new url', () => {388 instance.visitUrl('example.com')389 expect(instance.url).to.equal('example.com')390 expect(instance.state.url).to.equal('example.com')391 expect(cyVisitStub).to.be.calledWith('example.com')392 })393 it('adds a log for the visited url', () => {394 instance.visitUrl('cypress.io')395 expect(instance.logs[0].selector).to.be.null396 expect(instance.logs[0].name).to.equal('visit')397 expect(instance.logs[0].message).to.equal('cypress.io')398 })399 })400 context('#copyToClipboard', () => {401 const textToBeCopied = 'cy.get(\'.btn\').click()'402 afterEach(() => {403 delete window.isSecureContext404 delete navigator.clipboard405 delete document.execCommand406 })407 it('uses clipboard api when available', () => {408 const writeText = sinon.stub().resolves()409 window.isSecureContext = true410 navigator.clipboard = {411 writeText,412 }413 return instance.copyToClipboard(textToBeCopied).then(() => {414 expect(writeText).to.be.calledWith(textToBeCopied)415 })416 })417 it('falls back to execCommand when clipboard api not available', () => {418 const execCommand = sinon.stub()419 document.execCommand = execCommand420 instance.copyToClipboard(textToBeCopied).then(() => {421 expect(execCommand).to.be.calledWith('copy')422 })423 })424 })425 // https://github.com/cypress-io/cypress/issues/14658426 context('#recordMouseEvent', () => {427 beforeEach(() => {428 instance.testId = 'r2'429 })430 it('does not record events not sent by the user', () => {431 instance._recordMouseEvent(createEvent({ isTrusted: false }))432 expect(instance._previousMouseEvent).to.be.null433 })434 it('records the selector and element for an event', () => {435 const el = $('<div />')[0]436 instance._recordMouseEvent(createEvent({ target: el, type: 'mouseover' }))437 expect(instance._previousMouseEvent.selector).to.equal('.selector')438 expect(instance._previousMouseEvent.element).to.equal(el)439 })440 it('clears previous event on mouseout', () => {441 const el = $('<div />')[0]442 instance._previousMouseEvent = {443 selector: '.selector',444 element: el,445 }446 instance._recordMouseEvent(createEvent({ target: el, type: 'mouseout' }))447 expect(instance._previousMouseEvent).to.be.null448 })449 it('replaces previous mouse event if element is different', () => {450 const el1 = $('<div />')[0]451 const el2 = $('<p />')[0]452 instance._previousMouseEvent = {453 selector: '.previous-selector',454 element: el1,455 }456 instance._recordMouseEvent(createEvent({ target: el2, type: 'mouseover' }))457 expect(instance._previousMouseEvent.selector).to.equal('.selector')458 expect(instance._previousMouseEvent.element).to.equal(el2)459 })460 it('does not replace previous mouse event if element is the same', () => {461 const el = $('<div />')[0]462 instance._previousMouseEvent = {463 selector: '.previous-selector',464 element: el,465 }466 instance._recordMouseEvent(createEvent({ target: el, type: 'mousedown' }))467 expect(instance._previousMouseEvent.selector).to.equal('.previous-selector')468 expect(instance._previousMouseEvent.element).to.equal(el)469 })470 })471 context('#getName', () => {472 it('returns the event type by default', () => {473 const $el = $('<div />')474 const name = instance._getName(createEvent({ type: 'click' }), $el)475 expect(name).to.equal('click')476 })477 it('returns select when a select changes', () => {478 const $el = $('<select />')479 const name = instance._getName(createEvent({ type: 'change' }), $el)480 expect(name).to.equal('select')481 })482 it('returns type on keydown', () => {483 const $el = $('<input />')484 const name = instance._getName(createEvent({ type: 'keydown' }), $el)485 expect(name).to.equal('type')486 })487 it('returns check on radio button click', () => {488 const $el = $('<input type="radio" />')489 const name = instance._getName(createEvent({ type: 'click' }), $el)490 expect(name).to.equal('check')491 })492 it('returns check when checkbox is checked', () => {493 const $el = $('<input type="checkbox" checked />')494 const name = instance._getName(createEvent({ type: 'click' }), $el)495 expect(name).to.equal('check')496 })497 it('returns uncheck when checkbox is unchecked', () => {498 const $el = $('<input type="checkbox" />')499 const name = instance._getName(createEvent({ type: 'click' }), $el)500 expect(name).to.equal('uncheck')501 })502 })503 context('#getMessage', () => {504 it('returns null if the event has no value', () => {505 const $el = $('<div />')506 const message = instance._getMessage(createEvent({ type: 'click' }), $el)507 expect(message).to.be.null508 })509 it('returns target value if the event has a value', () => {510 const $el = $('<input value="blue" />')511 const message = instance._getMessage(createEvent({ type: 'change' }), $el)512 expect(message).to.equal('blue')513 })514 it('returns input value on keyup', () => {515 const $el = $('<input value="value" />')516 const message = instance._getMessage(createEvent({ type: 'keyup', key: 'e' }), $el)517 expect(message).to.equal('value')518 })519 it('returns input value on keyup for special keys', () => {520 const $el = $('<input value="value" />')521 const message = instance._getMessage(createEvent({ type: 'keydown', key: 'Backspace' }), $el)522 expect(message).to.equal('value')523 })524 it('returns input value with { escaped', () => {525 const $el = $('<input value="my{value}" />')526 const message = instance._getMessage(createEvent({ type: 'keydown', key: '}' }), $el)527 expect(message).to.equal('my{{}value}')528 })529 it('returns input value with {enter} on enter keydown', () => {530 const $el = $('<input value="value" />')531 const message = instance._getMessage(createEvent({ type: 'keydown', key: 'Enter' }), $el)532 expect(message).to.equal('value{enter}')533 })534 it('returns array if value is an array', () => {535 const $el = $('<select multiple><option value="0">0</option><option value="1">1</option></select>')536 $el.val(['0', '1'])537 const message = instance._getMessage(createEvent({ type: 'change' }), $el)538 expect(message).to.eql(['0', '1'])539 })540 })541 context('#recordEvent', () => {542 beforeEach(() => {543 instance.testId = 'r2'544 })545 it('does not record events not sent by the user', () => {546 instance._recordEvent(createEvent({ isTrusted: false }))547 expect(instance.logs).to.be.empty548 })549 it('does not prevent the action from reaching other event listeners', () => {550 const $el = $('<div />')551 const preventDefault = sinon.stub()552 const stopPropagation = sinon.stub()553 instance._recordEvent(createEvent({ target: $el, preventDefault, stopPropagation }))554 expect(preventDefault).not.to.be.called555 expect(stopPropagation).not.to.be.called556 })557 it('does not record events if the test has failed', () => {558 instance.testFailed()559 const $el = $('<div />')560 instance._recordEvent(createEvent({ target: $el }))561 expect(instance.logs).to.be.empty562 })563 it('does not record events inside the assertions menu', () => {564 const $el = $('<div class="__cypress-studio-assertions-menu" />')565 instance._recordEvent(createEvent({ target: $el }))566 expect(instance.logs).to.be.empty567 })568 it('closes the assertions menu when recording an event', () => {569 const $el = $('<div />')570 instance._recordEvent(createEvent({ target: $el }))571 expect(dom.closeStudioAssertionsMenu).to.be.called572 })573 it('does not close the assertions menu on events inside the assertions menu', () => {574 const $el = $('<div class="__cypress-studio-assertions-menu" />')575 instance._recordEvent(createEvent({ target: $el }))576 expect(dom.closeStudioAssertionsMenu).not.to.be.called577 })578 it('uses the selector playground to get a selector for the element', () => {579 const $el = $('<div />')580 instance._recordEvent(createEvent({ target: $el }))581 expect(getSelectorStub).to.be.calledWith($el)582 })583 it('uses the selector from a previously recorded mouse event on click', () => {584 const el = $('<div />')[0]585 instance._previousMouseEvent = {586 selector: '.previous-selector',587 element: el,588 }589 instance._recordEvent(createEvent({ type: 'click', target: el }))590 expect(instance.logs[0].name).to.equal('click')591 expect(instance.logs[0].selector).to.equal('.previous-selector')592 })593 it('clears previous mouse event after recording any event', () => {594 const el = $('<div />')[0]595 instance._previousMouseEvent = {596 selector: '.previous-selector',597 element: $('<input />')[0],598 }599 instance._recordEvent(createEvent({ type: 'click', target: el }))600 expect(instance._previousMouseEvent).to.be.null601 })602 it('records a clear event before recording a type event', () => {603 const $el = $('<input value="val" />')604 instance._recordEvent(createEvent({ type: 'keyup', key: 'l', target: $el }))605 expect(instance.logs.length).to.equal(2)606 expect(instance.logs[0].name).to.equal('clear')607 expect(instance.logs[0].message).to.equal(null)608 expect(instance.logs[1].name).to.equal('type')609 expect(instance.logs[1].message).to.equal('val')610 })611 it('removes an existing type if additional typing causes element to become empty', () => {612 instance.logs = [{613 id: 1,614 selector: '.selector',615 name: 'clear',616 message: null,617 }, {618 id: 2,619 selector: '.selector',620 name: 'type',621 message: 'a',622 }]623 const $el = $('<input value="" />')624 instance._recordEvent(createEvent({ type: 'keyup', key: 'Backspace', target: $el }))625 expect(instance.logs.length).to.equal(1)626 expect(instance.logs[0].name).to.equal('clear')627 expect(instance.logs[0].message).to.equal(null)628 })629 it('does not record a duplicate clear event if one already exists when typing', () => {630 instance.logs = [{631 id: 1,632 selector: '.selector',633 name: 'clear',634 message: null,635 }]636 const $el = $('<input value="val" />')637 instance._recordEvent(createEvent({ type: 'keyup', key: 'l', target: $el }))638 expect(instance.logs.length).to.equal(2)639 expect(instance.logs[0].name).to.equal('clear')640 expect(instance.logs[0].message).to.equal(null)641 expect(instance.logs[1].name).to.equal('type')642 expect(instance.logs[1].message).to.equal('val')643 })644 it('does not record keyup outside of input', () => {645 const $el = $('<div />')646 instance._recordEvent(createEvent({ type: 'keyup', key: 'a', target: $el }))647 expect(instance.logs).to.be.empty648 })649 it('does not record unneeded change events', () => {650 const $el = $('<input />')651 instance._recordEvent(createEvent({ type: 'change', target: $el }))652 expect(instance.logs).to.be.empty653 })654 it('does not record keyup for enter key', () => {655 const $el = $('<input value="val" />')656 instance._recordEvent(createEvent({ type: 'keyup', key: 'Enter', target: $el }))657 expect(instance.logs).to.be.empty658 })659 it('only records keydown for enter key', () => {660 const $el = $('<input value="" />')661 instance._recordEvent(createEvent({ type: 'keydown', key: 'a', target: $el }))662 expect(instance.logs).to.be.empty663 $el.val('a')664 instance._recordEvent(createEvent({ type: 'keydown', key: 'b', target: $el }))665 expect(instance.logs).to.be.empty666 $el.val('ab')667 instance._recordEvent(createEvent({ type: 'keydown', key: 'Enter', target: $el }))668 expect(instance.logs[1].name).to.equal('type')669 expect(instance.logs[1].message).to.equal('ab{enter}')670 })671 it('records multi select changes', () => {672 const $el = $('<select multiple><option value="0">0</option><option value="1">1</option></select>')673 $el.val(['0', '1'])674 instance._recordEvent(createEvent({ type: 'change', target: $el }))675 expect(instance.logs[0].name).to.eql('select')676 expect(instance.logs[0].message).to.eql(['0', '1'])677 })678 it('does not record events on <option>', () => {679 const $el = $('<option />')680 instance._recordEvent(createEvent({ target: $el }))681 expect(instance.logs).to.be.empty682 })683 it('does not record click events on <select>', () => {684 const $el = $('<select />')685 instance._recordEvent(createEvent({ type: 'click', target: $el }))686 expect(instance.logs).to.be.empty687 })688 it('adds events to the command log with incrementing ids', () => {689 const $el = $('<div />')690 instance._recordEvent(createEvent({ type: 'click', target: $el }))691 instance._recordEvent(createEvent({ type: 'click', target: $el }))692 expect(instance.logs.length).to.equal(2)693 expect(instance.logs[0].id).to.equal(1)694 expect(instance.logs[0].selector).to.equal('.selector')695 expect(instance.logs[0].name).to.equal('click')696 expect(instance.logs[0].message).to.equal(null)697 expect(instance.logs[1].id).to.equal(2)698 expect(instance.logs[1].selector).to.equal('.selector')699 expect(instance.logs[1].name).to.equal('click')700 expect(instance.logs[1].message).to.equal(null)701 })702 it('emits two reporter:log:add events for each log', () => {703 const $el = $('<button />')704 instance._recordEvent(createEvent({ type: 'click', target: $el }))705 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {706 hookId: 'r2-studio',707 id: 's1-get',708 instrument: 'command',709 isStudio: true,710 message: '.selector',711 name: 'get',712 numElements: 1,713 number: 1,714 state: 'passed',715 testId: 'r2',716 type: 'parent',717 })718 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {719 hookId: 'r2-studio',720 id: 's1',721 instrument: 'command',722 isStudio: true,723 message: null,724 name: 'click',725 numElements: 1,726 number: undefined,727 state: 'passed',728 testId: 'r2',729 type: 'child',730 })731 })732 it('emits stringified message for arrays', () => {733 const $el = $('<select multiple><option value="0">0</option><option value="1">1</option></select>')734 $el.val(['0', '1'])735 instance._recordEvent(createEvent({ type: 'change', target: $el }))736 expect(eventManager.emit).to.be.calledWithMatch('reporter:log:add', {737 message: '[0, 1]',738 })739 })740 })741 context('#updateLastLog', () => {742 it('does not filter if there are no existing logs', () => {743 const result = instance._updateLastLog('.selector', 'click', null)744 expect(result).to.be.false745 })746 it('does not filter if selectors do not match', () => {747 instance.logs = [{748 id: 1,749 selector: '.selector',750 name: 'type',751 message: 'a',752 }]753 const result = instance._updateLastLog('.different-selector', 'type', 'b')754 expect(result).to.be.false755 })756 it('modifies original log in place with updated value for typing events with same selector', () => {757 instance.logs = [{758 id: 1,759 selector: '.selector',760 name: 'type',761 message: 'a',762 }]763 const result = instance._updateLastLog('.selector', 'type', 'ab')764 expect(result).to.be.true765 expect(instance.logs[0].name).to.equal('type')766 expect(instance.logs[0].message).to.equal('ab')767 })768 it('converts clicks into clears on type and returns false', () => {769 instance.logs = [{770 id: 1,771 selector: '.selector',772 name: 'click',773 message: null,774 }]775 const result = instance._updateLastLog('.selector', 'type', 'a')776 expect(result).to.be.false777 expect(instance.logs[0].name).to.equal('clear')778 expect(instance.logs[0].message).to.be.null779 })780 it('emits reporter:log:state:changed with the child log when a log is updated', () => {781 instance.testId = 'r2'782 instance.logs = [{783 id: 1,784 selector: '.selector',785 name: 'type',786 message: 'a',787 }]788 instance._updateLastLog('.selector', 'type', 'ab')789 expect(eventManager.emit).to.be.calledWith('reporter:log:state:changed', {790 hookId: 'r2-studio',791 id: 's1',792 instrument: 'command',793 isStudio: true,794 message: 'ab',795 name: 'type',796 numElements: 1,797 number: undefined,798 state: 'passed',799 testId: 'r2',800 type: 'child',801 })802 })803 })804 context('#addAssertion', () => {805 beforeEach(() => {806 instance.testId = 'r2'807 })808 it('uses the selector playground to get a selector for the element', () => {809 const $el = $('<div />')810 instance._addAssertion($el, 'be.visible')811 expect(getSelectorStub).to.be.calledWith($el)812 })813 it('closes the assertions menu', () => {814 const $el = $('<div />')815 instance._addAssertion($el, 'be.visible')816 expect(dom.closeStudioAssertionsMenu).to.be.called817 })818 it('records assertions with one parameter', () => {819 const $el = $('<div />')820 instance._addAssertion($el, 'be.visible')821 expect(instance.logs.length).to.equal(1)822 expect(instance.logs[0].selector).to.equal('.selector')823 expect(instance.logs[0].name).to.equal('should')824 expect(instance.logs[0].message).to.have.ordered.members(['be.visible'])825 expect(instance.logs[0].isAssertion).to.be.true826 })827 it('records assertions with two parameters', () => {828 const $el = $('<div />')829 instance._addAssertion($el, 'have.text', 'my message')830 expect(instance.logs.length).to.equal(1)831 expect(instance.logs[0].selector).to.equal('.selector')832 expect(instance.logs[0].name).to.equal('should')833 expect(instance.logs[0].message).to.have.ordered.members(['have.text', 'my message'])834 expect(instance.logs[0].isAssertion).to.be.true835 })836 it('records assertions with three parameters', () => {837 const $el = $('<div />')838 instance._addAssertion($el, 'have.attr', 'data-target', '#my-div')839 expect(instance.logs.length).to.equal(1)840 expect(instance.logs[0].selector).to.equal('.selector')841 expect(instance.logs[0].name).to.equal('should')842 expect(instance.logs[0].message).to.have.ordered.members(['have.attr', 'data-target', '#my-div'])843 expect(instance.logs[0].isAssertion).to.be.true844 })845 it('adds assertions to the command log with incrementing ids', () => {846 const $el = $('<div />')847 instance._addAssertion($el, 'be.visible')848 instance._addAssertion($el, 'have.text', 'my message')849 expect(instance.logs.length).to.equal(2)850 expect(instance.logs[0].selector).to.equal('.selector')851 expect(instance.logs[0].name).to.equal('should')852 expect(instance.logs[0].message).to.have.ordered.members(['be.visible'])853 expect(instance.logs[0].isAssertion).to.be.true854 expect(instance.logs[1].selector).to.equal('.selector')855 expect(instance.logs[1].name).to.equal('should')856 expect(instance.logs[1].message).to.have.ordered.members(['have.text', 'my message'])857 expect(instance.logs[1].isAssertion).to.be.true858 })859 it('emits the first reporter:log:add event with get and the selector', () => {860 const $el = $('<div />')861 instance._addAssertion($el, 'be.visible')862 expect(eventManager.emit).to.be.calledTwice863 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {864 hookId: 'r2-studio',865 id: 's1-get',866 instrument: 'command',867 isStudio: true,868 message: '.selector',869 name: 'get',870 numElements: 1,871 number: 1,872 state: 'passed',873 testId: 'r2',874 type: 'parent',875 })876 })877 it('emits the second reporter:log:add for an assertion with one parameter', () => {878 const $el = $('<input type="radio" id="my-input" />')879 const message = 'expect **<input#my-input>** to not be checked'880 instance._addAssertion($el, 'not.be.checked')881 expect(eventManager.emit).to.be.calledTwice882 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {883 hookId: 'r2-studio',884 id: 's1',885 instrument: 'command',886 isStudio: true,887 message,888 name: 'assert',889 numElements: 1,890 number: undefined,891 state: 'passed',892 testId: 'r2',893 type: 'child',894 })895 })896 it('emits the second reporter:log:add for an assertion with two parameters', () => {897 const $el = $('<div class="container" />')898 const message = 'expect **<div.container>** to have text **my message**'899 instance._addAssertion($el, 'have.text', 'my message')900 expect(eventManager.emit).to.be.calledTwice901 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {902 hookId: 'r2-studio',903 id: 's1',904 instrument: 'command',905 isStudio: true,906 message,907 name: 'assert',908 numElements: 1,909 number: undefined,910 state: 'passed',911 testId: 'r2',912 type: 'child',913 })914 })915 it('emits the second reporter:log:add for an assertion with three parameters', () => {916 const $el = $('<button data-target="#my-div" />')917 const message = 'expect **<button>** to have attr **data-target** with the value **#my-div**'918 instance._addAssertion($el, 'have.attr', 'data-target', '#my-div')919 expect(eventManager.emit).to.be.calledTwice920 expect(eventManager.emit).to.be.calledWith('reporter:log:add', {921 hookId: 'r2-studio',922 id: 's1',923 instrument: 'command',924 isStudio: true,925 message,926 name: 'assert',927 numElements: 1,928 number: undefined,929 state: 'passed',930 testId: 'r2',931 type: 'child',932 })933 })934 })935 context('#openAssertionsMenu', () => {936 it('prevents the default right click event and propagation', () => {937 const $el = $('<div />')938 const preventDefault = sinon.stub()939 const stopPropagation = sinon.stub()940 instance._openAssertionsMenu(createEvent({ target: $el, preventDefault, stopPropagation }))941 expect(preventDefault).to.be.called942 expect(stopPropagation).to.be.called943 })944 it('closes existing assertions menu', () => {945 const $el = $('<div />')946 instance._openAssertionsMenu(createEvent({ target: $el }))947 expect(dom.closeStudioAssertionsMenu).to.be.called948 })949 it('opens the assertions menu', () => {950 const $el = $('<div />')951 instance._openAssertionsMenu(createEvent({ target: $el }))952 expect(dom.openStudioAssertionsMenu).to.be.called953 })954 it('does not close existing assertions menu or open another one if right click within menu', () => {955 const $el = $('<div class="__cypress-studio-assertions-menu" />')956 instance._openAssertionsMenu(createEvent({ target: $el }))957 expect(dom.closeStudioAssertionsMenu).not.to.be.called958 expect(dom.openStudioAssertionsMenu).not.to.be.called959 })960 })961 context('#generatePossibleAssertions', () => {962 it('generates assertions for an element with many attributes', () => {963 const $el = $('<div id="wrapper" class="container container-wide" data-channel="a1" data-content="pg-container">page content</div>')964 const possibleAssertions = instance._generatePossibleAssertions($el)965 expect(possibleAssertions.length).to.equal(5)966 expect(possibleAssertions[0].type).to.equal('have.text')967 expect(possibleAssertions[0].options.length).to.equal(1)968 expect(possibleAssertions[0].options[0].value).to.equal('page content')969 expect(possibleAssertions[1].type).to.equal('have.id')970 expect(possibleAssertions[1].options.length).to.equal(1)971 expect(possibleAssertions[1].options[0].value).to.equal('wrapper')972 expect(possibleAssertions[2].type).to.equal('have.class')973 expect(possibleAssertions[2].options.length).to.equal(2)974 expect(possibleAssertions[2].options[0].value).to.equal('container')975 expect(possibleAssertions[2].options[1].value).to.equal('container-wide')976 expect(possibleAssertions[3].type).to.equal('have.attr')977 expect(possibleAssertions[3].options.length).to.equal(2)978 expect(possibleAssertions[3].options[0].name).to.equal('data-channel')979 expect(possibleAssertions[3].options[0].value).to.equal('a1')980 expect(possibleAssertions[3].options[1].name).to.equal('data-content')981 expect(possibleAssertions[3].options[1].value).to.equal('pg-container')982 expect(possibleAssertions[4].type).to.equal('be.visible')983 expect(possibleAssertions[4].options).to.be.undefined984 })985 it('always generates be.visible but not have.text or have.value for elements without them', () => {986 const $el = $('<span />')987 const possibleAssertions = instance._generatePossibleAssertions($el)988 expect(possibleAssertions.length).to.equal(1)989 expect(possibleAssertions[0].type).to.equal('be.visible')990 expect(possibleAssertions[0].options).to.be.undefined991 })992 it('does not generate have.text for elements that cannot have text', () => {993 const $el = $('<textarea>placeholder</textarea>')994 const possibleAssertions = instance._generatePossibleAssertions($el)995 expect(possibleAssertions.length).to.equal(3)996 expect(possibleAssertions[0].type).to.equal('have.value')997 expect(possibleAssertions[0].options.length).to.equal(1)998 expect(possibleAssertions[0].options[0].value).to.equal('placeholder')999 expect(possibleAssertions[1].type).to.equal('be.visible')1000 expect(possibleAssertions[1].options).to.be.undefined1001 expect(possibleAssertions[2].type).to.equal('be.enabled')1002 expect(possibleAssertions[2].options).to.be.undefined1003 })1004 it('generates be.enabled for enabled elements', () => {1005 const $el = $('<button>button</button>')1006 const possibleAssertions = instance._generatePossibleAssertions($el)1007 expect(possibleAssertions.length).to.equal(3)1008 expect(possibleAssertions[0].type).to.equal('have.text')1009 expect(possibleAssertions[0].options.length).to.equal(1)1010 expect(possibleAssertions[0].options[0].value).to.equal('button')1011 expect(possibleAssertions[1].type).to.equal('be.visible')1012 expect(possibleAssertions[1].options).to.be.undefined1013 expect(possibleAssertions[2].type).to.equal('be.enabled')1014 expect(possibleAssertions[2].options).to.be.undefined1015 })1016 it('generates be.disabled for disabled elements', () => {1017 const $el = $('<button disabled>button</button>')1018 const possibleAssertions = instance._generatePossibleAssertions($el)1019 expect(possibleAssertions.length).to.equal(3)1020 expect(possibleAssertions[0].type).to.equal('have.text')1021 expect(possibleAssertions[0].options.length).to.equal(1)1022 expect(possibleAssertions[0].options[0].value).to.equal('button')1023 expect(possibleAssertions[1].type).to.equal('be.visible')1024 expect(possibleAssertions[1].options).to.be.undefined1025 expect(possibleAssertions[2].type).to.equal('be.disabled')1026 expect(possibleAssertions[2].options).to.be.undefined1027 })1028 it('generates not.be.checked for unchecked elements', () => {1029 const $el = $('<input type="radio" value="option1">')1030 const possibleAssertions = instance._generatePossibleAssertions($el)1031 expect(possibleAssertions.length).to.equal(5)1032 expect(possibleAssertions[0].type).to.equal('have.value')1033 expect(possibleAssertions[0].options.length).to.equal(1)1034 expect(possibleAssertions[0].options[0].value).to.equal('option1')1035 expect(possibleAssertions[1].type).to.equal('have.attr')1036 expect(possibleAssertions[1].options.length).to.equal(1)1037 expect(possibleAssertions[1].options[0].name).to.equal('type')1038 expect(possibleAssertions[1].options[0].value).to.equal('radio')1039 expect(possibleAssertions[2].type).to.equal('be.visible')1040 expect(possibleAssertions[2].options).to.be.undefined1041 expect(possibleAssertions[3].type).to.equal('be.enabled')1042 expect(possibleAssertions[3].options).to.be.undefined1043 expect(possibleAssertions[4].type).to.equal('not.be.checked')1044 expect(possibleAssertions[4].options).to.be.undefined1045 })1046 it('generates be.checked for checked elements', () => {1047 const $el = $('<input type="checkbox" value="option1" checked>')1048 const possibleAssertions = instance._generatePossibleAssertions($el)1049 expect(possibleAssertions.length).to.equal(5)1050 expect(possibleAssertions[0].type).to.equal('have.value')1051 expect(possibleAssertions[0].options.length).to.equal(1)1052 expect(possibleAssertions[0].options[0].value).to.equal('option1')1053 expect(possibleAssertions[1].type).to.equal('have.attr')1054 expect(possibleAssertions[1].options.length).to.equal(1)1055 expect(possibleAssertions[1].options[0].name).to.equal('type')1056 expect(possibleAssertions[1].options[0].value).to.equal('checkbox')1057 expect(possibleAssertions[2].type).to.equal('be.visible')1058 expect(possibleAssertions[2].options).to.be.undefined1059 expect(possibleAssertions[3].type).to.equal('be.enabled')1060 expect(possibleAssertions[3].options).to.be.undefined1061 expect(possibleAssertions[4].type).to.equal('be.checked')1062 expect(possibleAssertions[4].options).to.be.undefined1063 })1064 })...

Full Screen

Full Screen

studio-recorder.js

Source:studio-recorder.js Github

copy

Full Screen

...583 },584 })585 }586 _closeAssertionsMenu = () => {587 dom.closeStudioAssertionsMenu($(this._body))588 }589 _generatePossibleAssertions = ($el) => {590 const tagName = $el.prop('tagName')591 const possibleAssertions = []592 if (!tagNamesWithoutText.includes(tagName)) {593 const text = $el.text()594 if (text) {595 possibleAssertions.push({596 type: 'have.text',597 options: [{598 value: text,599 }],600 })601 }...

Full Screen

Full Screen

dom.js

Source:dom.js Github

copy

Full Screen

1import _ from 'lodash'2import retargetEvents from 'react-shadow-dom-retarget-events'3import $Cypress from '@packages/driver'4import $dimensions from './dimensions'5import { selectorPlaygroundHighlight } from './selector-playground/highlight'6import { studioAssertionsMenu } from './studio/assertions-menu'7// The '!' tells webpack to disable normal loaders, and keep loaders with `enforce: 'pre'` and `enforce: 'post'`8// This disables the CSSExtractWebpackPlugin and allows us to get the CSS as a raw string instead of saving it to a separate file.9import selectorPlaygroundCSS from '!./selector-playground/selector-playground.scss'10import studioAssertionsMenuCSS from '!./studio/assertions-menu.scss'11const $ = $Cypress.$12const styles = (styleString) => {13 return styleString.replace(/\s*\n\s*/g, '')14}15const resetStyles = `16 border: none !important;17 margin: 0 !important;18 padding: 0 !important;19`20function addHitBoxLayer (coords, $body) {21 $body = $body || $('body')22 const height = 1023 const width = 1024 const dotHeight = 425 const dotWidth = 426 const top = coords.y - height / 227 const left = coords.x - width / 228 const dotTop = height / 2 - dotHeight / 229 const dotLeft = width / 2 - dotWidth / 230 const boxStyles = styles(`31 ${resetStyles}32 position: absolute;33 top: ${top}px;34 left: ${left}px;35 width: ${width}px;36 height: ${height}px;37 background-color: red;38 border-radius: 5px;39 box-shadow: 0 0 5px #333;40 z-index: 2147483647;41 `)42 const $box = $(`<div class="__cypress-highlight" style="${boxStyles}" />`)43 const wrapper = $(`<div style="${styles(resetStyles)} position: relative" />`).appendTo($box)44 const dotStyles = styles(`45 ${resetStyles}46 position: absolute;47 top: ${dotTop}px;48 left: ${dotLeft}px;49 height: ${dotHeight}px;50 width: ${dotWidth}px;51 height: ${dotHeight}px;52 background-color: pink;53 border-radius: 5px;54 `)55 $(`<div style="${dotStyles}">`).appendTo(wrapper)56 return $box.appendTo($body)57}58function addElementBoxModelLayers ($el, $body) {59 $body = $body || $('body')60 const dimensions = $dimensions.getElementDimensions($el)61 const $container = $('<div class="__cypress-highlight">')62 .css({63 opacity: 0.7,64 position: 'absolute',65 zIndex: 2147483647,66 })67 const layers = {68 Content: '#9FC4E7',69 Padding: '#C1CD89',70 Border: '#FCDB9A',71 Margin: '#F9CC9D',72 }73 // create the margin / bottom / padding layers74 _.each(layers, (color, attr) => {75 let obj76 switch (attr) {77 case 'Content':78 // rearrange the contents offset so79 // its inside of our border + padding80 obj = {81 width: dimensions.width,82 height: dimensions.height,83 top: dimensions.offset.top + dimensions.borderTop + dimensions.paddingTop,84 left: dimensions.offset.left + dimensions.borderLeft + dimensions.paddingLeft,85 }86 break87 default:88 obj = {89 width: getDimensionsFor(dimensions, attr, 'width'),90 height: getDimensionsFor(dimensions, attr, 'height'),91 top: dimensions.offset.top,92 left: dimensions.offset.left,93 }94 }95 // if attr is margin then we need to additional96 // subtract what the actual marginTop + marginLeft97 // values are, since offset disregards margin completely98 if (attr === 'Margin') {99 obj.top -= dimensions.marginTop100 obj.left -= dimensions.marginLeft101 }102 if (attr === 'Padding') {103 obj.top += dimensions.borderTop104 obj.left += dimensions.borderLeft105 }106 // bail if the dimensions of this layer match the previous one107 // so we dont create unnecessary layers108 if (dimensionsMatchPreviousLayer(obj, $container)) return109 return createLayer($el, attr, color, $container, obj)110 })111 $container.appendTo($body)112 $container.children().each((index, el) => {113 const $el = $(el)114 const top = $el.data('top')115 const left = $el.data('left')116 // dont ask... for some reason we117 // have to run offset twice!118 _.times(2, () => {119 return $el.offset({ top, left })120 })121 })122 return $container123}124function getOrCreateHelperDom ({ $body, className, css }) {125 let $container = $body.find(`.${className}`)126 if ($container.length) {127 const shadowRoot = $container[0].shadowRoot128 return {129 $container,130 shadowRoot,131 $reactContainer: $(shadowRoot).find('.react-container'),132 }133 }134 $container = $('<div />')135 .addClass(className)136 .css({ position: 'static' })137 .appendTo($body)138 const shadowRoot = $container[0].attachShadow({ mode: 'open' })139 const $reactContainer = $('<div />')140 .addClass('react-container')141 .appendTo(shadowRoot)142 $('<style />', { html: css.toString() }).prependTo(shadowRoot)143 return { $container, shadowRoot, $reactContainer }144}145function getSelectorHighlightStyles ($el) {146 const borderSize = 2147 return $el.map((__, el) => {148 const $el = $(el)149 const offset = $el.offset()150 return {151 position: 'absolute',152 margin: 0,153 padding: 0,154 width: $el.outerWidth(),155 height: $el.outerHeight(),156 top: offset.top - borderSize,157 left: offset.left - borderSize,158 transform: $el.css('transform'),159 zIndex: getZIndex($el),160 }161 }).get()162}163function addOrUpdateSelectorPlaygroundHighlight ({ $el, $body, selector, showTooltip, onClick }) {164 const { $container, shadowRoot, $reactContainer } = getOrCreateHelperDom({165 $body,166 className: '__cypress-selector-playground',167 css: selectorPlaygroundCSS,168 })169 if (!$el) {170 selectorPlaygroundHighlight.unmount($reactContainer[0])171 $reactContainer.off('click')172 $container.remove()173 return174 }175 const styles = getSelectorHighlightStyles($el)176 if ($el.length === 1) {177 $reactContainer178 .off('click')179 .on('click', onClick)180 }181 selectorPlaygroundHighlight.render($reactContainer[0], {182 selector,183 appendTo: shadowRoot,184 showTooltip,185 styles,186 })187}188function getStudioAssertionsMenuDom ($body) {189 return getOrCreateHelperDom({190 $body,191 className: '__cypress-studio-assertions-menu',192 css: studioAssertionsMenuCSS,193 })194}195function openStudioAssertionsMenu ({ $el, $body, props }) {196 const { shadowRoot, $reactContainer } = getStudioAssertionsMenuDom($body)197 const selectorHighlightStyles = getSelectorHighlightStyles($el)[0]198 studioAssertionsMenu.render($reactContainer[0], {199 $el,200 selectorHighlightStyles,201 ...props,202 })203 retargetEvents(shadowRoot)204}205function closeStudioAssertionsMenu ($body) {206 const { $container, $reactContainer } = getStudioAssertionsMenuDom($body)207 studioAssertionsMenu.unmount($reactContainer[0])208 $container.remove()209}210function createLayer ($el, attr, color, container, dimensions) {211 const transform = $el.css('transform')212 const css = {213 transform,214 width: dimensions.width,215 height: dimensions.height,216 position: 'absolute',217 zIndex: getZIndex($el),218 backgroundColor: color,219 }220 return $('<div>')221 .css(css)222 .attr('data-top', dimensions.top)223 .attr('data-left', dimensions.left)224 .attr('data-layer', attr)225 .prependTo(container)226}227function dimensionsMatchPreviousLayer (obj, container) {228 // since we're prepending to the container that229 // means the previous layer is actually the first child element230 const previousLayer = container.children().first().get(0)231 // bail if there is no previous layer232 if (!previousLayer) {233 return234 }235 return obj.width === previousLayer.offsetWidth &&236 obj.height === previousLayer.offsetHeight237}238function getDimensionsFor (dimensions, attr, dimension) {239 return dimensions[`${dimension}With${attr}`]240}241function getZIndex (el) {242 if (/^(auto|0)$/.test(el.css('zIndex'))) {243 return 2147483647244 }245 return _.toNumber(el.css('zIndex'))246}247function isInViewport (win, el) {248 let rect = el.getBoundingClientRect()249 return (250 rect.top >= 0 &&251 rect.left >= 0 &&252 rect.bottom <= win.innerHeight &&253 rect.right <= win.innerWidth254 )255}256function scrollIntoView (win, el) {257 if (!el || isInViewport(win, el)) return258 el.scrollIntoView()259}260const sizzleRe = /sizzle/i261function getElementsForSelector ({ $root, selector, method, cypressDom }) {262 let $el = null263 try {264 if (method === 'contains') {265 $el = $root.find(cypressDom.getContainsSelector(selector))266 if ($el.length) {267 $el = cypressDom.getFirstDeepestElement($el)268 }269 } else {270 $el = $root.find(selector)271 }272 } catch (err) {273 // if not a sizzle error, ignore it and let $el be null274 if (!sizzleRe.test(err.stack)) throw err275 }276 return $el277}278export const dom = {279 addElementBoxModelLayers,280 addHitBoxLayer,281 addOrUpdateSelectorPlaygroundHighlight,282 openStudioAssertionsMenu,283 closeStudioAssertionsMenu,284 getElementsForSelector,285 getOuterSize: $dimensions.getOuterSize,286 scrollIntoView,...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1cy.closeStudioAssertionsMenu();2Cypress.Commands.add("closeStudioAssertionsMenu", () => {3 cy.get(".close-assertions-menu").click();4});5declare namespace Cypress {6 interface Chainable {7 closeStudioAssertionsMenu(): Chainable<Element>;8 }9}

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Cypress', () => {2 it('is awesome', () => {3 cy.closeStudioAssertionsMenu();4 });5});6Cypress.Commands.add('closeStudioAssertionsMenu', () => {7 cy.get('.studio-assertions-menu').click();8});9declare namespace Cypress {10 interface Chainable {11 closeStudioAssertionsMenu: () => void;12 }13}14describe('Cypress', () => {15 it('is awesome', () => {16 cy.closeStudioAssertionsMenu();17 });18});19module.exports = (on, config) => {20 on('task', {21 closeStudioAssertionsMenu: () => {22 cy.get('.studio-assertions-menu').click();23 },24 });25};26declare namespace Cypress {27 interface Chainable {28 closeStudioAssertionsMenu: () => void;29 }30}31Cypress.Commands.add('closeStudioAssertionsMenu', () => {32 cy.get('.studio-assertions-menu').click();33});34Cypress.Commands.add('closeStudioAssertionsMenu', () => {35 cy.get('.studio-assertions-menu').click();36});37declare namespace Cypress {38 interface Chainable {39 closeStudioAssertionsMenu: () => void;40 }41}42Cypress.Commands.add('closeStudioAssertionsMenu', () => {43 cy.get('.studio-assertions-menu').click();44});45declare namespace Cypress {46 interface Chainable {47 closeStudioAssertionsMenu: () =>

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('closeStudioAssertionsMenu', () => {2 cy.get('.studio-assertions-menu').click();3});4Cypress.Commands.add('closeStudioAssertionsMenu', () => {5 cy.get('.studio-assertions-menu').click();6});7Cypress.Commands.add('closeStudioAssertionsMenu', () => {8 cy.get('.studio-assertions-menu').click();9});10Cypress.Commands.add('closeStudioAssertionsMenu', () => {11 cy.get('.studio-assertions-menu').click();12});13Cypress.Commands.add('closeStudioAssertionsMenu', () => {14 cy.get('.studio-assertions-menu').click();15});16Cypress.Commands.add('closeStudioAssertionsMenu', () => {17 cy.get('.studio-assertions-menu').click();18});19Cypress.Commands.add('closeStudioAssertionsMenu', () => {20 cy.get('.studio-assertions-menu').click();21});22Cypress.Commands.add('closeStudioAssertionsMenu', () => {23 cy.get('.studio-assertions-menu').click();24});25Cypress.Commands.add('closeStudioAssertionsMenu', () => {26 cy.get('.studio-assertions-menu').click();27});28Cypress.Commands.add('closeStudioAssertionsMenu', () => {29 cy.get('.studio-assertions-menu').click();30});31Cypress.Commands.add('closeStudioAssertionsMenu', () => {32 cy.get('.studio-assertions-menu').click();33});34Cypress.Commands.add('closeStudioAssertionsMenu', () => {35 cy.get('.studio-assertions-menu').click();36});37Cypress.Commands.add('closeStudioAssertionsMenu', () => {38 cy.get('.studio-assertions-menu').click();39});

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('closeStudioAssertionsMenu', () => {2 cy.get('.studio-assertions-menu').find('.close').click();3});4Cypress.Commands.add('closeStudioAssertionsMenu', () => {5 cy.get('.studio-assertions-menu').find('.close').click();6});7Cypress.Commands.add('closeStudioAssertionsMenu', () => {8 cy.get('.studio-assertions-menu').find('.close').click();9});10Cypress.Commands.add('closeStudioAssertionsMenu', () => {11 cy.get('.studio-assertions-menu').find('.close').click();12});13Cypress.Commands.add('closeStudioAssertionsMenu', () => {14 cy.get('.studio-assertions-menu').find('.close').click();15});16Cypress.Commands.add('closeStudioAssertionsMenu', () => {17 cy.get('.studio-assertions-menu').find('.close').click();18});19Cypress.Commands.add('closeStudioAssertionsMenu', () => {20 cy.get('.studio-assertions-menu').find('.close').click();21});22Cypress.Commands.add('closeStudioAssertionsMenu', () => {23 cy.get('.studio-assertions-menu').find('.close').click();24});25Cypress.Commands.add('closeStudioAssertionsMenu', () => {26 cy.get('.studio-assertions-menu').find('.close').click();27});

Full Screen

Using AI Code Generation

copy

Full Screen

1closeStudioAssertionsMenu() {2 return cy.get('.studio-assertions-menu').find('.studio-assertions-menu__close').click();3}4cy.closeStudioAssertionsMenu();5cy.closeStudioAssertionsMenu();6cy.closeStudioAssertionsMenu();7cy.closeStudioAssertionsMenu();8cy.closeStudioAssertionsMenu();9cy.closeStudioAssertionsMenu();10cy.closeStudioAssertionsMenu();11cy.closeStudioAssertionsMenu();12cy.closeStudioAssertionsMenu();13cy.closeStudioAssertionsMenu();14cy.closeStudioAssertionsMenu();15cy.closeStudioAssertionsMenu();16cy.closeStudioAssertionsMenu();17cy.closeStudioAssertionsMenu();18cy.closeStudioAssertionsMenu();19cy.closeStudioAssertionsMenu();20cy.closeStudioAssertionsMenu();

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful