mirror of
https://github.com/OpenNebula/one.git
synced 2025-02-05 21:57:24 +03:00
Co-authored-by: Jorge Lobo <jlobo@opennebula.systems>
This commit is contained in:
parent
e08ad357f6
commit
8dbb55587f
@ -1,9 +1,16 @@
|
||||
{
|
||||
"port": 3001,
|
||||
"port": 2617,
|
||||
"numTestsKeptInMemory": 20,
|
||||
"env":{},
|
||||
"video": false,
|
||||
"viewportHeight": 720,
|
||||
"viewportWidth": 1280,
|
||||
"baseUrl": "http://localhost:3000"
|
||||
"baseUrl": "http://localhost:2616",
|
||||
"reporter": "mochawesome",
|
||||
"reporterOptions": {
|
||||
"reportDir": "cypress/results",
|
||||
"overwrite": false,
|
||||
"html": false,
|
||||
"json": true
|
||||
}
|
||||
}
|
||||
|
110
src/fireedge/cypress/command/index.js
Normal file
110
src/fireedge/cypress/command/index.js
Normal file
@ -0,0 +1,110 @@
|
||||
const cypress = require('cypress')
|
||||
const marge = require('mochawesome-report-generator')
|
||||
const { merge } = require('mochawesome-merge')
|
||||
const { existsSync, mkdirsSync, readFileSync, writeFileSync, removeSync } = require('fs-extra')
|
||||
const { dirname } = require('path')
|
||||
|
||||
const config = {
|
||||
browser: 'chrome',
|
||||
headless: true,
|
||||
spec: 'cypress/integration/**/*.spec.js'
|
||||
}
|
||||
|
||||
const generateReport = (options = {
|
||||
reportDir: 'cypress/results',
|
||||
reportFilename: 'merge-results',
|
||||
saveJson: true,
|
||||
saveHtml: false,
|
||||
files: [
|
||||
'./cypress/results/*.json'
|
||||
]
|
||||
}) => {
|
||||
return merge(options).then(report => marge.create(report, options))
|
||||
}
|
||||
|
||||
const parseReport = (dataReport = '') => {
|
||||
if (dataReport && Array.isArray(dataReport) && dataReport.slice(-1).pop()) {
|
||||
const pathMergeJson = dataReport.slice(-1).pop()
|
||||
const bsname = dirname(pathMergeJson)
|
||||
const fileData = readFileSync(pathMergeJson, 'utf8')
|
||||
if (fileData) {
|
||||
const dataJSON = JSON.parse(fileData)
|
||||
const parsedJSON = {}
|
||||
|
||||
// version
|
||||
parsedJSON.version = dataJSON.meta.mochawesome.version
|
||||
|
||||
// examples
|
||||
const examples = []
|
||||
// results -19
|
||||
if (dataJSON.results) {
|
||||
dataJSON.results.forEach(results => {
|
||||
const pathTest = results.fullFile
|
||||
// results.suites -28
|
||||
if (results && results.suites && Array.isArray(results.suites)) {
|
||||
results.suites.forEach(suites => {
|
||||
// result.suites.tests -36
|
||||
if (suites && suites.tests && Array.isArray(suites.tests)) {
|
||||
suites.tests.forEach(test => {
|
||||
const parsedTest = {}
|
||||
parsedTest.id = pathTest
|
||||
parsedTest.description = test.title || null
|
||||
parsedTest.full_description = test.fullTitle || null
|
||||
parsedTest.status = test.pass ? 'passed' : 'failed'
|
||||
parsedTest.file_path = pathTest
|
||||
parsedTest.line_number = null
|
||||
parsedTest.run_time = test.duration || null
|
||||
parsedTest.pending_message = null
|
||||
|
||||
if (test.fail && test.code && test.code.length) {
|
||||
parsedTest.exception = {
|
||||
class: test.err.message,
|
||||
backtrace: test.err.estack && [test.err.estack],
|
||||
message: test.code
|
||||
}
|
||||
}
|
||||
examples.push(parsedTest)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
parsedJSON.examples = examples
|
||||
|
||||
// summary
|
||||
parsedJSON.summary = {
|
||||
duration: dataJSON.stats.duration,
|
||||
example_count: dataJSON.stats.tests,
|
||||
failure_count: dataJSON.stats.failures,
|
||||
pending_count: dataJSON.stats.pending,
|
||||
errors_outside_of_examples_count: dataJSON.stats.other
|
||||
}
|
||||
|
||||
// summary_line
|
||||
parsedJSON.summary_line = `${dataJSON.stats.testsRegistered} examples, ${dataJSON.stats.failures} failures`
|
||||
|
||||
// clear results folder
|
||||
removeSync(bsname)
|
||||
|
||||
// create path
|
||||
if (!existsSync(bsname)) {
|
||||
mkdirsSync(bsname)
|
||||
}
|
||||
|
||||
// create JSON file
|
||||
writeFileSync(`${bsname}/results.json`, JSON.stringify(parsedJSON))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cypress.run(config).then(
|
||||
() => {
|
||||
generateReport().then(parseReport)
|
||||
},
|
||||
error => {
|
||||
generateReport().then(parseReport)
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
)
|
@ -7,5 +7,21 @@
|
||||
"endpoints": {
|
||||
"login": "/api/auth/",
|
||||
"userInfo": "/api/user/info"
|
||||
},
|
||||
"provision": {
|
||||
"provision": "hybrid+",
|
||||
"provider": "aws",
|
||||
"nameProvider": "aws-frankfurt",
|
||||
"descriptionProvider": "Elastic cluster on AWS in Frakfurt",
|
||||
"descriptionProviderEdited": "Elastic cluster on AWS in Frakfurt Edited!",
|
||||
"descriptionProvision": "Provision description",
|
||||
"key": "access key",
|
||||
"keyEdited": "access key Edited!",
|
||||
"secretKey": "secret access key",
|
||||
"secretKeyEdited": "secret access key Edited!",
|
||||
"nameProvision": "aws-cluster",
|
||||
"numberInstances": "1",
|
||||
"amiImage": "ami-0b793c1e0d1dc4d28",
|
||||
"instanceType": "i3-metal"
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// / <reference types="Cypress" />
|
||||
|
||||
context('Dashboard', () => {
|
||||
before(() => {
|
||||
cy.visit('/');
|
||||
cy.login();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
it('has dashboard title on header', () => {
|
||||
cy.get('[data-cy=header-title]').should('have.text', 'dashboard');
|
||||
});
|
||||
});
|
@ -1,272 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Actions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/actions')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/interacting-with-elements
|
||||
|
||||
it('.type() - type into a DOM element', () => {
|
||||
// https://on.cypress.io/type
|
||||
cy.get('.action-email')
|
||||
.type('fake@email.com').should('have.value', 'fake@email.com')
|
||||
|
||||
// .type() with special character sequences
|
||||
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
|
||||
.type('{del}{selectall}{backspace}')
|
||||
|
||||
// .type() with key modifiers
|
||||
.type('{alt}{option}') //these are equivalent
|
||||
.type('{ctrl}{control}') //these are equivalent
|
||||
.type('{meta}{command}{cmd}') //these are equivalent
|
||||
.type('{shift}')
|
||||
|
||||
// Delay each keypress by 0.1 sec
|
||||
.type('slow.typing@email.com', { delay: 100 })
|
||||
.should('have.value', 'slow.typing@email.com')
|
||||
|
||||
cy.get('.action-disabled')
|
||||
// Ignore error checking prior to type
|
||||
// like whether the input is visible or disabled
|
||||
.type('disabled error checking', { force: true })
|
||||
.should('have.value', 'disabled error checking')
|
||||
})
|
||||
|
||||
it('.focus() - focus on a DOM element', () => {
|
||||
// https://on.cypress.io/focus
|
||||
cy.get('.action-focus').focus()
|
||||
.should('have.class', 'focus')
|
||||
.prev().should('have.attr', 'style', 'color: orange;')
|
||||
})
|
||||
|
||||
it('.blur() - blur off a DOM element', () => {
|
||||
// https://on.cypress.io/blur
|
||||
cy.get('.action-blur').type('About to blur').blur()
|
||||
.should('have.class', 'error')
|
||||
.prev().should('have.attr', 'style', 'color: red;')
|
||||
})
|
||||
|
||||
it('.clear() - clears an input or textarea element', () => {
|
||||
// https://on.cypress.io/clear
|
||||
cy.get('.action-clear').type('Clear this text')
|
||||
.should('have.value', 'Clear this text')
|
||||
.clear()
|
||||
.should('have.value', '')
|
||||
})
|
||||
|
||||
it('.submit() - submit a form', () => {
|
||||
// https://on.cypress.io/submit
|
||||
cy.get('.action-form')
|
||||
.find('[type="text"]').type('HALFOFF')
|
||||
cy.get('.action-form').submit()
|
||||
.next().should('contain', 'Your form has been submitted!')
|
||||
})
|
||||
|
||||
it('.click() - click on a DOM element', () => {
|
||||
// https://on.cypress.io/click
|
||||
cy.get('.action-btn').click()
|
||||
|
||||
// You can click on 9 specific positions of an element:
|
||||
// -----------------------------------
|
||||
// | topLeft top topRight |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | left center right |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | bottomLeft bottom bottomRight |
|
||||
// -----------------------------------
|
||||
|
||||
// clicking in the center of the element is the default
|
||||
cy.get('#action-canvas').click()
|
||||
|
||||
cy.get('#action-canvas').click('topLeft')
|
||||
cy.get('#action-canvas').click('top')
|
||||
cy.get('#action-canvas').click('topRight')
|
||||
cy.get('#action-canvas').click('left')
|
||||
cy.get('#action-canvas').click('right')
|
||||
cy.get('#action-canvas').click('bottomLeft')
|
||||
cy.get('#action-canvas').click('bottom')
|
||||
cy.get('#action-canvas').click('bottomRight')
|
||||
|
||||
// .click() accepts an x and y coordinate
|
||||
// that controls where the click occurs :)
|
||||
|
||||
cy.get('#action-canvas')
|
||||
.click(80, 75) // click 80px on x coord and 75px on y coord
|
||||
.click(170, 75)
|
||||
.click(80, 165)
|
||||
.click(100, 185)
|
||||
.click(125, 190)
|
||||
.click(150, 185)
|
||||
.click(170, 165)
|
||||
|
||||
// click multiple elements by passing multiple: true
|
||||
cy.get('.action-labels>.label').click({ multiple: true })
|
||||
|
||||
// Ignore error checking prior to clicking
|
||||
cy.get('.action-opacity>.btn').click({ force: true })
|
||||
})
|
||||
|
||||
it('.dblclick() - double click on a DOM element', () => {
|
||||
// https://on.cypress.io/dblclick
|
||||
|
||||
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
||||
// that hides the div and shows an input on double click
|
||||
cy.get('.action-div').dblclick().should('not.be.visible')
|
||||
cy.get('.action-input-hidden').should('be.visible')
|
||||
})
|
||||
|
||||
it('.check() - check a checkbox or radio element', () => {
|
||||
// https://on.cypress.io/check
|
||||
|
||||
// By default, .check() will check all
|
||||
// matching checkbox or radio elements in succession, one after another
|
||||
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
// .check() accepts a value argument
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio1').should('be.checked')
|
||||
|
||||
// .check() accepts an array of values
|
||||
cy.get('.action-multiple-checkboxes [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox2']).should('be.checked')
|
||||
|
||||
// Ignore error checking prior to checking
|
||||
cy.get('.action-checkboxes [disabled]')
|
||||
.check({ force: true }).should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio3', { force: true }).should('be.checked')
|
||||
})
|
||||
|
||||
it('.uncheck() - uncheck a checkbox element', () => {
|
||||
// https://on.cypress.io/uncheck
|
||||
|
||||
// By default, .uncheck() will uncheck all matching
|
||||
// checkbox elements in succession, one after another
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.not('[disabled]')
|
||||
.uncheck().should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts a value argument
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check('checkbox1')
|
||||
.uncheck('checkbox1').should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts an array of values
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox3'])
|
||||
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
|
||||
|
||||
// Ignore error checking prior to unchecking
|
||||
cy.get('.action-check [disabled]')
|
||||
.uncheck({ force: true }).should('not.be.checked')
|
||||
})
|
||||
|
||||
it('.select() - select an option in a <select> element', () => {
|
||||
// https://on.cypress.io/select
|
||||
|
||||
// Select option(s) with matching text content
|
||||
cy.get('.action-select').select('apples')
|
||||
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['apples', 'oranges', 'bananas'])
|
||||
|
||||
// Select option(s) with matching value
|
||||
cy.get('.action-select').select('fr-bananas')
|
||||
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
|
||||
})
|
||||
|
||||
it('.scrollIntoView() - scroll an element into view', () => {
|
||||
// https://on.cypress.io/scrollintoview
|
||||
|
||||
// normally all of these buttons are hidden,
|
||||
// because they're not within
|
||||
// the viewable area of their parent
|
||||
// (we need to scroll to see them)
|
||||
cy.get('#scroll-horizontal button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// scroll the button into view, as if the user had scrolled
|
||||
cy.get('#scroll-horizontal button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-vertical button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress handles the scroll direction needed
|
||||
cy.get('#scroll-vertical button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-both button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress knows to scroll to the right and down
|
||||
cy.get('#scroll-both button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.trigger() - trigger an event on a DOM element', () => {
|
||||
// https://on.cypress.io/trigger
|
||||
|
||||
// To interact with a range input (slider)
|
||||
// we need to set its value & trigger the
|
||||
// event to signal it changed
|
||||
|
||||
// Here, we invoke jQuery's val() method to set
|
||||
// the value and trigger the 'change' event
|
||||
cy.get('.trigger-input-range')
|
||||
.invoke('val', 25)
|
||||
.trigger('change')
|
||||
.get('input[type=range]').siblings('p')
|
||||
.should('have.text', '25')
|
||||
})
|
||||
|
||||
it('cy.scrollTo() - scroll the window or element to a position', () => {
|
||||
|
||||
// https://on.cypress.io/scrollTo
|
||||
|
||||
// You can scroll to 9 specific positions of an element:
|
||||
// -----------------------------------
|
||||
// | topLeft top topRight |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | left center right |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | bottomLeft bottom bottomRight |
|
||||
// -----------------------------------
|
||||
|
||||
// if you chain .scrollTo() off of cy, we will
|
||||
// scroll the entire window
|
||||
cy.scrollTo('bottom')
|
||||
|
||||
cy.get('#scrollable-horizontal').scrollTo('right')
|
||||
|
||||
// or you can scroll to a specific coordinate:
|
||||
// (x axis, y axis) in pixels
|
||||
cy.get('#scrollable-vertical').scrollTo(250, 250)
|
||||
|
||||
// or you can scroll to a specific percentage
|
||||
// of the (width, height) of the element
|
||||
cy.get('#scrollable-both').scrollTo('75%', '25%')
|
||||
|
||||
// control the easing of the scroll (default is 'swing')
|
||||
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
|
||||
|
||||
// control the duration of the scroll (in ms)
|
||||
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
|
||||
})
|
||||
})
|
@ -1,42 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Aliasing', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/aliasing')
|
||||
})
|
||||
|
||||
it('.as() - alias a DOM element for later use', () => {
|
||||
// https://on.cypress.io/as
|
||||
|
||||
// Alias a DOM element for use later
|
||||
// We don't have to traverse to the element
|
||||
// later in our code, we reference it with @
|
||||
|
||||
cy.get('.as-table').find('tbody>tr')
|
||||
.first().find('td').first()
|
||||
.find('button').as('firstBtn')
|
||||
|
||||
// when we reference the alias, we place an
|
||||
// @ in front of its name
|
||||
cy.get('@firstBtn').click()
|
||||
|
||||
cy.get('@firstBtn')
|
||||
.should('have.class', 'btn-success')
|
||||
.and('contain', 'Changed')
|
||||
})
|
||||
|
||||
it('.as() - alias a route for later use', () => {
|
||||
|
||||
// Alias the route to wait for its response
|
||||
cy.server()
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
})
|
||||
})
|
@ -1,168 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Assertions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/assertions')
|
||||
})
|
||||
|
||||
describe('Implicit Assertions', () => {
|
||||
it('.should() - make an assertion about the current subject', () => {
|
||||
// https://on.cypress.io/should
|
||||
cy.get('.assertion-table')
|
||||
.find('tbody tr:last')
|
||||
.should('have.class', 'success')
|
||||
.find('td')
|
||||
.first()
|
||||
// checking the text of the <td> element in various ways
|
||||
.should('have.text', 'Column content')
|
||||
.should('contain', 'Column content')
|
||||
.should('have.html', 'Column content')
|
||||
// chai-jquery uses "is()" to check if element matches selector
|
||||
.should('match', 'td')
|
||||
// to match text content against a regular expression
|
||||
// first need to invoke jQuery method text()
|
||||
// and then match using regular expression
|
||||
.invoke('text')
|
||||
.should('match', /column content/i)
|
||||
|
||||
// a better way to check element's text content against a regular expression
|
||||
// is to use "cy.contains"
|
||||
// https://on.cypress.io/contains
|
||||
cy.get('.assertion-table')
|
||||
.find('tbody tr:last')
|
||||
// finds first <td> element with text content matching regular expression
|
||||
.contains('td', /column content/i)
|
||||
.should('be.visible')
|
||||
|
||||
// for more information about asserting element's text
|
||||
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
|
||||
})
|
||||
|
||||
it('.and() - chain multiple assertions together', () => {
|
||||
// https://on.cypress.io/and
|
||||
cy.get('.assertions-link')
|
||||
.should('have.class', 'active')
|
||||
.and('have.attr', 'href')
|
||||
.and('include', 'cypress.io')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Explicit Assertions', () => {
|
||||
// https://on.cypress.io/assertions
|
||||
it('expect - make an assertion about a specified subject', () => {
|
||||
// We can use Chai's BDD style assertions
|
||||
expect(true).to.be.true
|
||||
const o = { foo: 'bar' }
|
||||
|
||||
expect(o).to.equal(o)
|
||||
expect(o).to.deep.equal({ foo: 'bar' })
|
||||
// matching text using regular expression
|
||||
expect('FooBar').to.match(/bar$/i)
|
||||
})
|
||||
|
||||
it('pass your own callback function to should()', () => {
|
||||
// Pass a function to should that can have any number
|
||||
// of explicit assertions within it.
|
||||
// The ".should(cb)" function will be retried
|
||||
// automatically until it passes all your explicit assertions or times out.
|
||||
cy.get('.assertions-p')
|
||||
.find('p')
|
||||
.should(($p) => {
|
||||
// https://on.cypress.io/$
|
||||
// return an array of texts from all of the p's
|
||||
// @ts-ignore TS6133 unused variable
|
||||
const texts = $p.map((i, el) => Cypress.$(el).text())
|
||||
|
||||
// jquery map returns jquery object
|
||||
// and .get() convert this to simple array
|
||||
const paragraphs = texts.get()
|
||||
|
||||
// array should have length of 3
|
||||
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
|
||||
|
||||
// use second argument to expect(...) to provide clear
|
||||
// message with each assertion
|
||||
expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([
|
||||
'Some text from first p',
|
||||
'More text from second p',
|
||||
'And even more text from third p',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
it('finds element by class name regex', () => {
|
||||
cy.get('.docs-header')
|
||||
.find('div')
|
||||
// .should(cb) callback function will be retried
|
||||
.should(($div) => {
|
||||
expect($div).to.have.length(1)
|
||||
|
||||
const className = $div[0].className
|
||||
|
||||
expect(className).to.match(/heading-/)
|
||||
})
|
||||
// .then(cb) callback is not retried,
|
||||
// it either passes or fails
|
||||
.then(($div) => {
|
||||
expect($div, 'text content').to.have.text('Introduction')
|
||||
})
|
||||
})
|
||||
|
||||
it('can throw any error', () => {
|
||||
cy.get('.docs-header')
|
||||
.find('div')
|
||||
.should(($div) => {
|
||||
if ($div.length !== 1) {
|
||||
// you can throw your own errors
|
||||
throw new Error('Did not find 1 element')
|
||||
}
|
||||
|
||||
const className = $div[0].className
|
||||
|
||||
if (!className.match(/heading-/)) {
|
||||
throw new Error(`Could not find class "heading-" in ${className}`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('matches unknown text between two elements', () => {
|
||||
/**
|
||||
* Text from the first element.
|
||||
* @type {string}
|
||||
*/
|
||||
let text
|
||||
|
||||
/**
|
||||
* Normalizes passed text,
|
||||
* useful before comparing text with spaces and different capitalization.
|
||||
* @param {string} s Text to normalize
|
||||
*/
|
||||
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.first')
|
||||
.then(($first) => {
|
||||
// save text from the first element
|
||||
text = normalizeText($first.text())
|
||||
})
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.second')
|
||||
.should(($div) => {
|
||||
// we can massage text before comparing
|
||||
const secondText = normalizeText($div.text())
|
||||
|
||||
expect(secondText, 'second text').to.equal(text)
|
||||
})
|
||||
})
|
||||
|
||||
it('assert - assert shape of an object', () => {
|
||||
const person = {
|
||||
name: 'Joe',
|
||||
age: 20,
|
||||
}
|
||||
|
||||
assert.isObject(person, 'value is object')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,56 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Connectors', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/connectors')
|
||||
})
|
||||
|
||||
it('.each() - iterate over an array of elements', () => {
|
||||
// https://on.cypress.io/each
|
||||
cy.get('.connectors-each-ul>li')
|
||||
.each(($el, index, $list) => {
|
||||
console.log($el, index, $list)
|
||||
})
|
||||
})
|
||||
|
||||
it('.its() - get properties on the current subject', () => {
|
||||
// https://on.cypress.io/its
|
||||
cy.get('.connectors-its-ul>li')
|
||||
// calls the 'length' property yielding that value
|
||||
.its('length')
|
||||
.should('be.gt', 2)
|
||||
})
|
||||
|
||||
it('.invoke() - invoke a function on the current subject', () => {
|
||||
// our div is hidden in our script.js
|
||||
// $('.connectors-div').hide()
|
||||
|
||||
// https://on.cypress.io/invoke
|
||||
cy.get('.connectors-div').should('be.hidden')
|
||||
// call the jquery method 'show' on the 'div.container'
|
||||
.invoke('show')
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.spread() - spread an array as individual args to callback function', () => {
|
||||
// https://on.cypress.io/spread
|
||||
const arr = ['foo', 'bar', 'baz']
|
||||
|
||||
cy.wrap(arr).spread((foo, bar, baz) => {
|
||||
expect(foo).to.eq('foo')
|
||||
expect(bar).to.eq('bar')
|
||||
expect(baz).to.eq('baz')
|
||||
})
|
||||
})
|
||||
|
||||
it('.then() - invoke a callback function with the current subject', () => {
|
||||
// https://on.cypress.io/then
|
||||
cy.get('.connectors-list > li')
|
||||
.then(($lis) => {
|
||||
expect($lis, '3 items').to.have.length(3)
|
||||
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
|
||||
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
|
||||
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,78 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Cookies', () => {
|
||||
beforeEach(() => {
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
cy.visit('https://example.cypress.io/commands/cookies')
|
||||
|
||||
// clear cookies again after visiting to remove
|
||||
// any 3rd party cookies picked up such as cloudflare
|
||||
cy.clearCookies()
|
||||
})
|
||||
|
||||
it('cy.getCookie() - get a browser cookie', () => {
|
||||
// https://on.cypress.io/getcookie
|
||||
cy.get('#getCookie .set-a-cookie').click()
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
})
|
||||
|
||||
it('cy.getCookies() - get browser cookies', () => {
|
||||
// https://on.cypress.io/getcookies
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#getCookies .set-a-cookie').click()
|
||||
|
||||
// cy.getCookies() yields an array of cookies
|
||||
cy.getCookies().should('have.length', 1).should((cookies) => {
|
||||
|
||||
// each cookie has these properties
|
||||
expect(cookies[0]).to.have.property('name', 'token')
|
||||
expect(cookies[0]).to.have.property('value', '123ABC')
|
||||
expect(cookies[0]).to.have.property('httpOnly', false)
|
||||
expect(cookies[0]).to.have.property('secure', false)
|
||||
expect(cookies[0]).to.have.property('domain')
|
||||
expect(cookies[0]).to.have.property('path')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.setCookie() - set a browser cookie', () => {
|
||||
// https://on.cypress.io/setcookie
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.setCookie('foo', 'bar')
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('foo').should('have.property', 'value', 'bar')
|
||||
})
|
||||
|
||||
it('cy.clearCookie() - clear a browser cookie', () => {
|
||||
// https://on.cypress.io/clearcookie
|
||||
cy.getCookie('token').should('be.null')
|
||||
|
||||
cy.get('#clearCookie .set-a-cookie').click()
|
||||
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookie('token').should('be.null')
|
||||
|
||||
cy.getCookie('token').should('be.null')
|
||||
})
|
||||
|
||||
it('cy.clearCookies() - clear browser cookies', () => {
|
||||
// https://on.cypress.io/clearcookies
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#clearCookies .set-a-cookie').click()
|
||||
|
||||
cy.getCookies().should('have.length', 1)
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookies()
|
||||
|
||||
cy.getCookies().should('be.empty')
|
||||
})
|
||||
})
|
@ -1,222 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Cypress.Commands', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/custom-commands
|
||||
|
||||
it('.add() - create a custom command', () => {
|
||||
Cypress.Commands.add('console', {
|
||||
prevSubject: true,
|
||||
}, (subject, method) => {
|
||||
// the previous subject is automatically received
|
||||
// and the commands arguments are shifted
|
||||
|
||||
// allow us to change the console method used
|
||||
method = method || 'log'
|
||||
|
||||
// log the subject to the console
|
||||
// @ts-ignore TS7017
|
||||
console[method]('The subject is', subject)
|
||||
|
||||
// whatever we return becomes the new subject
|
||||
// we don't want to change the subject so
|
||||
// we return whatever was passed in
|
||||
return subject
|
||||
})
|
||||
|
||||
// @ts-ignore TS2339
|
||||
cy.get('button').console('info').then(($button) => {
|
||||
// subject is still $button
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Cookies', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/cookies
|
||||
it('.debug() - enable or disable debugging', () => {
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
// Cypress will now log in the console when
|
||||
// cookies are set or cleared
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
})
|
||||
|
||||
it('.preserveOnce() - preserve cookies by key', () => {
|
||||
// normally cookies are reset after each test
|
||||
cy.getCookie('fakeCookie').should('not.be.ok')
|
||||
|
||||
// preserving a cookie will not clear it when
|
||||
// the next test starts
|
||||
cy.setCookie('lastCookie', '789XYZ')
|
||||
Cypress.Cookies.preserveOnce('lastCookie')
|
||||
})
|
||||
|
||||
it('.defaults() - set defaults for all cookies', () => {
|
||||
// now any cookie with the name 'session_id' will
|
||||
// not be cleared before each new test runs
|
||||
Cypress.Cookies.defaults({
|
||||
whitelist: 'session_id',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Server', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// Permanently override server options for
|
||||
// all instances of cy.server()
|
||||
|
||||
// https://on.cypress.io/cypress-server
|
||||
it('.defaults() - change default config of server', () => {
|
||||
Cypress.Server.defaults({
|
||||
delay: 0,
|
||||
force404: false,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.arch', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get CPU architecture name of underlying OS', () => {
|
||||
// https://on.cypress.io/arch
|
||||
expect(Cypress.arch).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.config()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get and set configuration options', () => {
|
||||
// https://on.cypress.io/config
|
||||
let myConfig = Cypress.config()
|
||||
|
||||
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
|
||||
expect(myConfig).to.have.property('baseUrl', null)
|
||||
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
|
||||
expect(myConfig).to.have.property('requestTimeout', 5000)
|
||||
expect(myConfig).to.have.property('responseTimeout', 30000)
|
||||
expect(myConfig).to.have.property('viewportHeight', 660)
|
||||
expect(myConfig).to.have.property('viewportWidth', 1000)
|
||||
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
|
||||
expect(myConfig).to.have.property('waitForAnimations', true)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
|
||||
|
||||
// this will change the config for the rest of your tests!
|
||||
Cypress.config('pageLoadTimeout', 20000)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
|
||||
|
||||
Cypress.config('pageLoadTimeout', 60000)
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.dom', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/dom
|
||||
it('.isHidden() - determine if a DOM element is hidden', () => {
|
||||
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
|
||||
let visibleP = Cypress.$('.dom-p p.visible').get(0)
|
||||
|
||||
// our first paragraph has css class 'hidden'
|
||||
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
|
||||
expect(Cypress.dom.isHidden(visibleP)).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.env()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// We can set environment variables for highly dynamic values
|
||||
|
||||
// https://on.cypress.io/environment-variables
|
||||
it('Get environment variables', () => {
|
||||
// https://on.cypress.io/env
|
||||
// set multiple environment variables
|
||||
Cypress.env({
|
||||
host: 'veronica.dev.local',
|
||||
api_server: 'http://localhost:8888/v1/',
|
||||
})
|
||||
|
||||
// get environment variable
|
||||
expect(Cypress.env('host')).to.eq('veronica.dev.local')
|
||||
|
||||
// set environment variable
|
||||
Cypress.env('api_server', 'http://localhost:8888/v2/')
|
||||
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
|
||||
|
||||
// get all environment variable
|
||||
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
|
||||
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.log', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Control what is printed to the Command Log', () => {
|
||||
// https://on.cypress.io/cypress-log
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.platform', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get underlying OS name', () => {
|
||||
// https://on.cypress.io/platform
|
||||
expect(Cypress.platform).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.version', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current version of Cypress being run', () => {
|
||||
// https://on.cypress.io/version
|
||||
expect(Cypress.version).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.spec', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current spec information', () => {
|
||||
// https://on.cypress.io/spec
|
||||
// wrap the object so we can inspect it easily by clicking in the command log
|
||||
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute'])
|
||||
})
|
||||
})
|
@ -1,114 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
/// JSON fixture file can be loaded directly using
|
||||
// the built-in JavaScript bundler
|
||||
// @ts-ignore
|
||||
const requiredExample = require('../../fixtures/example')
|
||||
|
||||
context('Files', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/files')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
// load example.json fixture file and store
|
||||
// in the test context object
|
||||
cy.fixture('example.json').as('example')
|
||||
})
|
||||
|
||||
it('cy.fixture() - load a fixture', () => {
|
||||
// https://on.cypress.io/fixture
|
||||
|
||||
// Instead of writing a response inline you can
|
||||
// use a fixture file's content.
|
||||
|
||||
cy.server()
|
||||
cy.fixture('example.json').as('comment')
|
||||
// when application makes an Ajax request matching "GET comments/*"
|
||||
// Cypress will intercept it and reply with object
|
||||
// from the "comment" alias
|
||||
cy.route('GET', 'comments/*', '@comment').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// you can also just write the fixture in the route
|
||||
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// or write fx to represent fixture
|
||||
// by default it assumes it's .json
|
||||
cy.route('GET', 'comments/*', 'fx:example').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
})
|
||||
|
||||
it('cy.fixture() or require - load a fixture', function () {
|
||||
// we are inside the "function () { ... }"
|
||||
// callback and can use test context object "this"
|
||||
// "this.example" was loaded in "beforeEach" function callback
|
||||
expect(this.example, 'fixture in the test context')
|
||||
.to.deep.equal(requiredExample)
|
||||
|
||||
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
||||
// @ts-ignore
|
||||
cy.wrap(this.example, 'fixture vs require')
|
||||
.should('deep.equal', requiredExample)
|
||||
})
|
||||
|
||||
it('cy.readFile() - read a files contents', () => {
|
||||
// https://on.cypress.io/readfile
|
||||
|
||||
// You can read a file and yield its contents
|
||||
// The filePath is relative to your project's root.
|
||||
cy.readFile('cypress.json').then((json) => {
|
||||
expect(json).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.writeFile() - write to a file', () => {
|
||||
// https://on.cypress.io/writefile
|
||||
|
||||
// You can write to a file
|
||||
|
||||
// Use a response from a request to automatically
|
||||
// generate a fixture file for use later
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
cy.writeFile('cypress/fixtures/users.json', response.body)
|
||||
})
|
||||
cy.fixture('users').should((users) => {
|
||||
expect(users[0].name).to.exist
|
||||
})
|
||||
|
||||
// JavaScript arrays and objects are stringified
|
||||
// and formatted into text.
|
||||
cy.writeFile('cypress/fixtures/profile.json', {
|
||||
id: 8739,
|
||||
name: 'Jane',
|
||||
email: 'jane@example.com',
|
||||
})
|
||||
|
||||
cy.fixture('profile').should((profile) => {
|
||||
expect(profile.name).to.eq('Jane')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,52 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Local Storage', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/local-storage')
|
||||
})
|
||||
// Although local storage is automatically cleared
|
||||
// in between tests to maintain a clean state
|
||||
// sometimes we need to clear the local storage manually
|
||||
|
||||
it('cy.clearLocalStorage() - clear all data in local storage', () => {
|
||||
// https://on.cypress.io/clearlocalstorage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// clearLocalStorage() yields the localStorage object
|
||||
cy.clearLocalStorage().should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.be.null
|
||||
})
|
||||
|
||||
// Clear key matching string in Local Storage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage('prop1').should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.eq('blue')
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// Clear keys matching regex in Local Storage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage(/prop1|2/).should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,32 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Location', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/location')
|
||||
})
|
||||
|
||||
it('cy.hash() - get the current URL hash', () => {
|
||||
// https://on.cypress.io/hash
|
||||
cy.hash().should('be.empty')
|
||||
})
|
||||
|
||||
it('cy.location() - get window.location', () => {
|
||||
// https://on.cypress.io/location
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.be.empty
|
||||
expect(location.href).to.eq('https://example.cypress.io/commands/location')
|
||||
expect(location.host).to.eq('example.cypress.io')
|
||||
expect(location.hostname).to.eq('example.cypress.io')
|
||||
expect(location.origin).to.eq('https://example.cypress.io')
|
||||
expect(location.pathname).to.eq('/commands/location')
|
||||
expect(location.port).to.eq('')
|
||||
expect(location.protocol).to.eq('https:')
|
||||
expect(location.search).to.be.empty
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.url() - get the current URL', () => {
|
||||
// https://on.cypress.io/url
|
||||
cy.url().should('eq', 'https://example.cypress.io/commands/location')
|
||||
})
|
||||
})
|
@ -1,83 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Misc', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/misc')
|
||||
})
|
||||
|
||||
it('.end() - end the command chain', () => {
|
||||
// https://on.cypress.io/end
|
||||
|
||||
// cy.end is useful when you want to end a chain of commands
|
||||
// and force Cypress to re-query from the root element
|
||||
cy.get('.misc-table').within(() => {
|
||||
// ends the current chain and yields null
|
||||
cy.contains('Cheryl').click().end()
|
||||
|
||||
// queries the entire table again
|
||||
cy.contains('Charles').click()
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.exec() - execute a system command', () => {
|
||||
// https://on.cypress.io/exec
|
||||
|
||||
// execute a system command.
|
||||
// so you can take actions necessary for
|
||||
// your test outside the scope of Cypress.
|
||||
cy.exec('echo Jane Lane')
|
||||
.its('stdout').should('contain', 'Jane Lane')
|
||||
|
||||
// we can use Cypress.platform string to
|
||||
// select appropriate command
|
||||
// https://on.cypress/io/platform
|
||||
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
|
||||
|
||||
if (Cypress.platform === 'win32') {
|
||||
cy.exec('print cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
} else {
|
||||
cy.exec('cat cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
|
||||
cy.exec('pwd')
|
||||
.its('code').should('eq', 0)
|
||||
}
|
||||
})
|
||||
|
||||
it('cy.focused() - get the DOM element that has focus', () => {
|
||||
// https://on.cypress.io/focused
|
||||
cy.get('.misc-form').find('#name').click()
|
||||
cy.focused().should('have.id', 'name')
|
||||
|
||||
cy.get('.misc-form').find('#description').click()
|
||||
cy.focused().should('have.id', 'description')
|
||||
})
|
||||
|
||||
context('Cypress.Screenshot', function () {
|
||||
it('cy.screenshot() - take a screenshot', () => {
|
||||
// https://on.cypress.io/screenshot
|
||||
cy.screenshot('my-image')
|
||||
})
|
||||
|
||||
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
|
||||
Cypress.Screenshot.defaults({
|
||||
blackout: ['.foo'],
|
||||
capture: 'viewport',
|
||||
clip: { x: 0, y: 0, width: 200, height: 200 },
|
||||
scale: false,
|
||||
disableTimersAndAnimations: true,
|
||||
screenshotOnRunFailure: true,
|
||||
beforeScreenshot () { },
|
||||
afterScreenshot () { },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.wrap() - wrap an object', () => {
|
||||
// https://on.cypress.io/wrap
|
||||
cy.wrap({ foo: 'bar' })
|
||||
.should('have.property', 'foo')
|
||||
.and('include', 'bar')
|
||||
})
|
||||
})
|
@ -1,56 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Navigation', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io')
|
||||
cy.get('.navbar-nav').contains('Commands').click()
|
||||
cy.get('.dropdown-menu').contains('Navigation').click()
|
||||
})
|
||||
|
||||
it('cy.go() - go back or forward in the browser\'s history', () => {
|
||||
// https://on.cypress.io/go
|
||||
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
cy.go('back')
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
cy.go('forward')
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
// clicking back
|
||||
cy.go(-1)
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
// clicking forward
|
||||
cy.go(1)
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
})
|
||||
|
||||
it('cy.reload() - reload the page', () => {
|
||||
// https://on.cypress.io/reload
|
||||
cy.reload()
|
||||
|
||||
// reload the page without using the cache
|
||||
cy.reload(true)
|
||||
})
|
||||
|
||||
it('cy.visit() - visit a remote url', () => {
|
||||
// https://on.cypress.io/visit
|
||||
|
||||
// Visit any sub-domain of your current domain
|
||||
|
||||
// Pass options to the visit
|
||||
cy.visit('https://example.cypress.io/commands/navigation', {
|
||||
timeout: 50000, // increase total time for the visit to resolve
|
||||
onBeforeLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
onLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
@ -1,194 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Network Requests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/network-requests')
|
||||
})
|
||||
|
||||
// Manage AJAX / XHR requests in your app
|
||||
|
||||
it('cy.server() - control behavior of network requests and responses', () => {
|
||||
// https://on.cypress.io/server
|
||||
|
||||
cy.server().should((server) => {
|
||||
// the default options on server
|
||||
// you can override any of these options
|
||||
expect(server.delay).to.eq(0)
|
||||
expect(server.method).to.eq('GET')
|
||||
expect(server.status).to.eq(200)
|
||||
expect(server.headers).to.be.null
|
||||
expect(server.response).to.be.null
|
||||
expect(server.onRequest).to.be.undefined
|
||||
expect(server.onResponse).to.be.undefined
|
||||
expect(server.onAbort).to.be.undefined
|
||||
|
||||
// These options control the server behavior
|
||||
// affecting all requests
|
||||
|
||||
// pass false to disable existing route stubs
|
||||
expect(server.enable).to.be.true
|
||||
// forces requests that don't match your routes to 404
|
||||
expect(server.force404).to.be.false
|
||||
// whitelists requests from ever being logged or stubbed
|
||||
expect(server.whitelist).to.be.a('function')
|
||||
})
|
||||
|
||||
cy.server({
|
||||
method: 'POST',
|
||||
delay: 1000,
|
||||
status: 422,
|
||||
response: {},
|
||||
})
|
||||
|
||||
// any route commands will now inherit the above options
|
||||
// from the server. anything we pass specifically
|
||||
// to route will override the defaults though.
|
||||
})
|
||||
|
||||
it('cy.request() - make an XHR request', () => {
|
||||
// https://on.cypress.io/request
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.should((response) => {
|
||||
expect(response.status).to.eq(200)
|
||||
expect(response.body).to.have.length(500)
|
||||
expect(response).to.have.property('headers')
|
||||
expect(response).to.have.property('duration')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('cy.request() - verify response using BDD syntax', () => {
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.then((response) => {
|
||||
// https://on.cypress.io/assertions
|
||||
expect(response).property('status').to.equal(200)
|
||||
expect(response).property('body').to.have.length(500)
|
||||
expect(response).to.include.keys('headers', 'duration')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() with query parameters', () => {
|
||||
// will execute request
|
||||
// https://jsonplaceholder.cypress.io/comments?postId=1&id=3
|
||||
cy.request({
|
||||
url: 'https://jsonplaceholder.cypress.io/comments',
|
||||
qs: {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
},
|
||||
})
|
||||
.its('body')
|
||||
.should('be.an', 'array')
|
||||
.and('have.length', 1)
|
||||
.its('0') // yields first element of the array
|
||||
.should('contain', {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - pass result to the second request', () => {
|
||||
// first, let's find out the userId of the first user we have
|
||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||
.its('body.0') // yields the first element of the returned list
|
||||
.then((user) => {
|
||||
expect(user).property('id').to.be.a('number')
|
||||
// make a new post on behalf of the user
|
||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||
userId: user.id,
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
})
|
||||
})
|
||||
// note that the value here is the returned value of the 2nd request
|
||||
// which is the new post object
|
||||
.then((response) => {
|
||||
expect(response).property('status').to.equal(201) // new entity created
|
||||
expect(response).property('body').to.contain({
|
||||
id: 101, // there are already 100 posts, so new entity gets id 101
|
||||
title: 'Cypress Test Runner',
|
||||
})
|
||||
// we don't know the user id here - since it was in above closure
|
||||
// so in this test just confirm that the property is there
|
||||
expect(response.body).property('userId').to.be.a('number')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - save response in the shared test context', () => {
|
||||
// https://on.cypress.io/variables-and-aliases
|
||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||
.its('body.0') // yields the first element of the returned list
|
||||
.as('user') // saves the object in the test context
|
||||
.then(function () {
|
||||
// NOTE 👀
|
||||
// By the time this callback runs the "as('user')" command
|
||||
// has saved the user object in the test context.
|
||||
// To access the test context we need to use
|
||||
// the "function () { ... }" callback form,
|
||||
// otherwise "this" points at a wrong or undefined object!
|
||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||
userId: this.user.id,
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
})
|
||||
.its('body').as('post') // save the new post from the response
|
||||
})
|
||||
.then(function () {
|
||||
// When this callback runs, both "cy.request" API commands have finished
|
||||
// and the test context has "user" and "post" objects set.
|
||||
// Let's verify them.
|
||||
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.route() - route responses to matching requests', () => {
|
||||
// https://on.cypress.io/route
|
||||
|
||||
let message = 'whoa, this comment does not exist'
|
||||
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
// Listen to POST to comments
|
||||
cy.route('POST', '/comments').as('postComment')
|
||||
|
||||
// we have code that posts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-post').click()
|
||||
cy.wait('@postComment')
|
||||
|
||||
// get the route
|
||||
cy.get('@postComment').should((xhr) => {
|
||||
expect(xhr.requestBody).to.include('email')
|
||||
expect(xhr.requestHeaders).to.have.property('Content-Type')
|
||||
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
|
||||
})
|
||||
|
||||
// Stub a response to PUT comments/ ****
|
||||
cy.route({
|
||||
method: 'PUT',
|
||||
url: 'comments/*',
|
||||
status: 404,
|
||||
response: { error: message },
|
||||
delay: 500,
|
||||
}).as('putComment')
|
||||
|
||||
// we have code that puts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-put').click()
|
||||
|
||||
cy.wait('@putComment')
|
||||
|
||||
// our 404 statusCode logic in scripts.js executed
|
||||
cy.get('.network-put-comment').should('contain', message)
|
||||
})
|
||||
})
|
@ -1,87 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Querying', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/querying')
|
||||
})
|
||||
|
||||
// The most commonly used query is 'cy.get()', you can
|
||||
// think of this like the '$' in jQuery
|
||||
|
||||
it('cy.get() - query DOM elements', () => {
|
||||
// https://on.cypress.io/get
|
||||
|
||||
cy.get('#query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('.query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('#querying .well>button:first').should('contain', 'Button')
|
||||
// ↲
|
||||
// Use CSS selectors just like jQuery
|
||||
|
||||
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
|
||||
|
||||
// 'cy.get()' yields jQuery object, you can get its attribute
|
||||
// by invoking `.attr()` method
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('attr', 'data-test-id')
|
||||
.should('equal', 'test-example')
|
||||
|
||||
// or you can get element's CSS property
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('css', 'position')
|
||||
.should('equal', 'static')
|
||||
|
||||
// or use assertions directly during 'cy.get()'
|
||||
// https://on.cypress.io/assertions
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.should('have.attr', 'data-test-id', 'test-example')
|
||||
.and('have.css', 'position', 'static')
|
||||
})
|
||||
|
||||
it('cy.contains() - query DOM elements with matching content', () => {
|
||||
// https://on.cypress.io/contains
|
||||
cy.get('.query-list')
|
||||
.contains('bananas')
|
||||
.should('have.class', 'third')
|
||||
|
||||
// we can pass a regexp to `.contains()`
|
||||
cy.get('.query-list')
|
||||
.contains(/^b\w+/)
|
||||
.should('have.class', 'third')
|
||||
|
||||
cy.get('.query-list')
|
||||
.contains('apples')
|
||||
.should('have.class', 'first')
|
||||
|
||||
// passing a selector to contains will
|
||||
// yield the selector containing the text
|
||||
cy.get('#querying')
|
||||
.contains('ul', 'oranges')
|
||||
.should('have.class', 'query-list')
|
||||
|
||||
cy.get('.query-button')
|
||||
.contains('Save Form')
|
||||
.should('have.class', 'btn')
|
||||
})
|
||||
|
||||
it('.within() - query DOM elements within a specific element', () => {
|
||||
// https://on.cypress.io/within
|
||||
cy.get('.query-form').within(() => {
|
||||
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
|
||||
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.root() - query the root DOM element', () => {
|
||||
// https://on.cypress.io/root
|
||||
|
||||
// By default, root is the document
|
||||
cy.root().should('match', 'html')
|
||||
|
||||
cy.get('.query-ul').within(() => {
|
||||
// In this within, the root is now the ul DOM element
|
||||
cy.root().should('have.class', 'query-ul')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,95 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Spies, Stubs, and Clock', () => {
|
||||
it('cy.spy() - wrap a method in a spy', () => {
|
||||
// https://on.cypress.io/spy
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
foo () {},
|
||||
}
|
||||
|
||||
const spy = cy.spy(obj, 'foo').as('anyArgs')
|
||||
|
||||
obj.foo()
|
||||
|
||||
expect(spy).to.be.called
|
||||
})
|
||||
|
||||
it('cy.spy() retries until assertions pass', () => {
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* Prints the argument passed
|
||||
* @param x {any}
|
||||
*/
|
||||
foo (x) {
|
||||
console.log('obj.foo called with', x)
|
||||
},
|
||||
}
|
||||
|
||||
cy.spy(obj, 'foo').as('foo')
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('first')
|
||||
}, 500)
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('second')
|
||||
}, 2500)
|
||||
|
||||
cy.get('@foo').should('have.been.calledTwice')
|
||||
})
|
||||
|
||||
it('cy.stub() - create a stub and/or replace a function with stub', () => {
|
||||
// https://on.cypress.io/stub
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* prints both arguments to the console
|
||||
* @param a {string}
|
||||
* @param b {string}
|
||||
*/
|
||||
foo (a, b) {
|
||||
console.log('a', a, 'b', b)
|
||||
},
|
||||
}
|
||||
|
||||
const stub = cy.stub(obj, 'foo').as('foo')
|
||||
|
||||
obj.foo('foo', 'bar')
|
||||
|
||||
expect(stub).to.be.called
|
||||
})
|
||||
|
||||
it('cy.clock() - control time in the browser', () => {
|
||||
// https://on.cypress.io/clock
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#clock-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
})
|
||||
|
||||
it('cy.tick() - move time in the browser', () => {
|
||||
// https://on.cypress.io/tick
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
cy.tick(10000) // 10 seconds passed
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449610')
|
||||
})
|
||||
})
|
@ -1,121 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Traversal', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/traversal')
|
||||
})
|
||||
|
||||
it('.children() - get child DOM elements', () => {
|
||||
// https://on.cypress.io/children
|
||||
cy.get('.traversal-breadcrumb')
|
||||
.children('.active')
|
||||
.should('contain', 'Data')
|
||||
})
|
||||
|
||||
it('.closest() - get closest ancestor DOM element', () => {
|
||||
// https://on.cypress.io/closest
|
||||
cy.get('.traversal-badge')
|
||||
.closest('ul')
|
||||
.should('have.class', 'list-group')
|
||||
})
|
||||
|
||||
it('.eq() - get a DOM element at a specific index', () => {
|
||||
// https://on.cypress.io/eq
|
||||
cy.get('.traversal-list>li')
|
||||
.eq(1).should('contain', 'siamese')
|
||||
})
|
||||
|
||||
it('.filter() - get DOM elements that match the selector', () => {
|
||||
// https://on.cypress.io/filter
|
||||
cy.get('.traversal-nav>li')
|
||||
.filter('.active').should('contain', 'About')
|
||||
})
|
||||
|
||||
it('.find() - get descendant DOM elements of the selector', () => {
|
||||
// https://on.cypress.io/find
|
||||
cy.get('.traversal-pagination')
|
||||
.find('li').find('a')
|
||||
.should('have.length', 7)
|
||||
})
|
||||
|
||||
it('.first() - get first DOM element', () => {
|
||||
// https://on.cypress.io/first
|
||||
cy.get('.traversal-table td')
|
||||
.first().should('contain', '1')
|
||||
})
|
||||
|
||||
it('.last() - get last DOM element', () => {
|
||||
// https://on.cypress.io/last
|
||||
cy.get('.traversal-buttons .btn')
|
||||
.last().should('contain', 'Submit')
|
||||
})
|
||||
|
||||
it('.next() - get next sibling DOM element', () => {
|
||||
// https://on.cypress.io/next
|
||||
cy.get('.traversal-ul')
|
||||
.contains('apples').next().should('contain', 'oranges')
|
||||
})
|
||||
|
||||
it('.nextAll() - get all next sibling DOM elements', () => {
|
||||
// https://on.cypress.io/nextall
|
||||
cy.get('.traversal-next-all')
|
||||
.contains('oranges')
|
||||
.nextAll().should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.nextUntil() - get next sibling DOM elements until next el', () => {
|
||||
// https://on.cypress.io/nextuntil
|
||||
cy.get('#veggies')
|
||||
.nextUntil('#nuts').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.not() - remove DOM elements from set of DOM elements', () => {
|
||||
// https://on.cypress.io/not
|
||||
cy.get('.traversal-disabled .btn')
|
||||
.not('[disabled]').should('not.contain', 'Disabled')
|
||||
})
|
||||
|
||||
it('.parent() - get parent DOM element from DOM elements', () => {
|
||||
// https://on.cypress.io/parent
|
||||
cy.get('.traversal-mark')
|
||||
.parent().should('contain', 'Morbi leo risus')
|
||||
})
|
||||
|
||||
it('.parents() - get parent DOM elements from DOM elements', () => {
|
||||
// https://on.cypress.io/parents
|
||||
cy.get('.traversal-cite')
|
||||
.parents().should('match', 'blockquote')
|
||||
})
|
||||
|
||||
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
|
||||
// https://on.cypress.io/parentsuntil
|
||||
cy.get('.clothes-nav')
|
||||
.find('.active')
|
||||
.parentsUntil('.clothes-nav')
|
||||
.should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prev() - get previous sibling DOM element', () => {
|
||||
// https://on.cypress.io/prev
|
||||
cy.get('.birds').find('.active')
|
||||
.prev().should('contain', 'Lorikeets')
|
||||
})
|
||||
|
||||
it('.prevAll() - get all previous sibling DOM elements', () => {
|
||||
// https://on.cypress.io/prevAll
|
||||
cy.get('.fruits-list').find('.third')
|
||||
.prevAll().should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
|
||||
// https://on.cypress.io/prevUntil
|
||||
cy.get('.foods-list').find('#nuts')
|
||||
.prevUntil('#veggies').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.siblings() - get all sibling DOM elements', () => {
|
||||
// https://on.cypress.io/siblings
|
||||
cy.get('.traversal-pills .active')
|
||||
.siblings().should('have.length', 2)
|
||||
})
|
||||
})
|
@ -1,133 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Utilities', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/utilities')
|
||||
})
|
||||
|
||||
it('Cypress._ - call a lodash method', () => {
|
||||
// https://on.cypress.io/_
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
let ids = Cypress._.chain(response.body).map('id').take(3).value()
|
||||
|
||||
expect(ids).to.deep.eq([1, 2, 3])
|
||||
})
|
||||
})
|
||||
|
||||
it('Cypress.$ - call a jQuery method', () => {
|
||||
// https://on.cypress.io/$
|
||||
let $li = Cypress.$('.utility-jquery li:first')
|
||||
|
||||
cy.wrap($li)
|
||||
.should('not.have.class', 'active')
|
||||
.click()
|
||||
.should('have.class', 'active')
|
||||
})
|
||||
|
||||
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
|
||||
// https://on.cypress.io/blob
|
||||
cy.get('.utility-blob').then(($div) =>
|
||||
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||
// get the dataUrl string for the javascript-logo
|
||||
Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
|
||||
.then((dataUrl) => {
|
||||
// create an <img> element and set its src to the dataUrl
|
||||
let img = Cypress.$('<img />', { src: dataUrl })
|
||||
|
||||
// need to explicitly return cy here since we are initially returning
|
||||
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
||||
// append the image
|
||||
$div.append(img)
|
||||
|
||||
cy.get('.utility-blob img').click()
|
||||
.should('have.attr', 'src', dataUrl)
|
||||
}))
|
||||
})
|
||||
|
||||
it('Cypress.minimatch - test out glob patterns against strings', () => {
|
||||
// https://on.cypress.io/minimatch
|
||||
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
})
|
||||
|
||||
expect(matching, 'matching wildcard').to.be.true
|
||||
|
||||
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
|
||||
// ** matches against all downstream path segments
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
|
||||
matchBase: true,
|
||||
})
|
||||
expect(matching, 'comments').to.be.true
|
||||
|
||||
// whereas * matches only the next path segment
|
||||
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
|
||||
matchBase: false,
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
})
|
||||
|
||||
|
||||
it('Cypress.moment() - format or parse dates using a moment method', () => {
|
||||
// https://on.cypress.io/moment
|
||||
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
|
||||
|
||||
expect(time).to.be.a('string')
|
||||
|
||||
cy.get('.utility-moment').contains('3:38 PM')
|
||||
.should('have.class', 'badge')
|
||||
|
||||
// the time in the element should be between 3pm and 5pm
|
||||
const start = Cypress.moment('3:00 PM', 'LT')
|
||||
const end = Cypress.moment('5:00 PM', 'LT')
|
||||
|
||||
cy.get('.utility-moment .badge')
|
||||
.should(($el) => {
|
||||
// parse American time like "3:38 PM"
|
||||
const m = Cypress.moment($el.text().trim(), 'LT')
|
||||
|
||||
// display hours + minutes + AM|PM
|
||||
const f = 'h:mm A'
|
||||
|
||||
expect(m.isBetween(start, end),
|
||||
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('Cypress.Promise - instantiate a bluebird promise', () => {
|
||||
// https://on.cypress.io/promise
|
||||
let waited = false
|
||||
|
||||
/**
|
||||
* @return Bluebird<string>
|
||||
*/
|
||||
function waitOneSecond () {
|
||||
// return a promise that resolves after 1 second
|
||||
// @ts-ignore TS2351 (new Cypress.Promise)
|
||||
return new Cypress.Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// set waited to true
|
||||
waited = true
|
||||
|
||||
// resolve with 'foo' string
|
||||
resolve('foo')
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
cy.then(() =>
|
||||
// return a promise to cy.then() that
|
||||
// is awaited until it resolves
|
||||
// @ts-ignore TS7006
|
||||
waitOneSecond().then((str) => {
|
||||
expect(str).to.eq('foo')
|
||||
expect(waited).to.be.true
|
||||
}))
|
||||
})
|
||||
})
|
@ -1,59 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Viewport', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/viewport')
|
||||
})
|
||||
|
||||
it('cy.viewport() - set the viewport size and dimension', () => {
|
||||
// https://on.cypress.io/viewport
|
||||
|
||||
cy.get('#navbar').should('be.visible')
|
||||
cy.viewport(320, 480)
|
||||
|
||||
// the navbar should have collapse since our screen is smaller
|
||||
cy.get('#navbar').should('not.be.visible')
|
||||
cy.get('.navbar-toggle').should('be.visible').click()
|
||||
cy.get('.nav').find('a').should('be.visible')
|
||||
|
||||
// lets see what our app looks like on a super large screen
|
||||
cy.viewport(2999, 2999)
|
||||
|
||||
// cy.viewport() accepts a set of preset sizes
|
||||
// to easily set the screen to a device's width and height
|
||||
|
||||
// We added a cy.wait() between each viewport change so you can see
|
||||
// the change otherwise it is a little too fast to see :)
|
||||
|
||||
cy.viewport('macbook-15')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-13')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-11')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-2')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-mini')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6+')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-5')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-3')
|
||||
cy.wait(200)
|
||||
|
||||
// cy.viewport() accepts an orientation for all presets
|
||||
// the default orientation is 'portrait'
|
||||
cy.viewport('ipad-2', 'portrait')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4', 'landscape')
|
||||
cy.wait(200)
|
||||
|
||||
// The viewport will be reset back to the default dimensions
|
||||
// in between tests (the default can be set in cypress.json)
|
||||
})
|
||||
})
|
@ -1,34 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Waiting', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/waiting')
|
||||
})
|
||||
// BE CAREFUL of adding unnecessary wait times.
|
||||
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
it('cy.wait() - wait for a specific amount of time', () => {
|
||||
cy.get('.wait-input1').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input2').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input3').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
})
|
||||
|
||||
it('cy.wait() - wait for a specific route', () => {
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// wait for GET comments/1
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
})
|
||||
|
||||
})
|
@ -1,22 +0,0 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Window', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/window')
|
||||
})
|
||||
|
||||
it('cy.window() - get the global window object', () => {
|
||||
// https://on.cypress.io/window
|
||||
cy.window().should('have.property', 'top')
|
||||
})
|
||||
|
||||
it('cy.document() - get the document object', () => {
|
||||
// https://on.cypress.io/document
|
||||
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
|
||||
})
|
||||
|
||||
it('cy.title() - get the title', () => {
|
||||
// https://on.cypress.io/title
|
||||
cy.title().should('include', 'Kitchen Sink')
|
||||
})
|
||||
})
|
@ -1,23 +0,0 @@
|
||||
// / <reference types="Cypress" />
|
||||
|
||||
context('Header', () => {
|
||||
before(() => {
|
||||
cy.visit('/');
|
||||
cy.login();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
it('has username on header', () => {
|
||||
cy.get('[data-cy=header-user-button]').click();
|
||||
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
cy.get('[data-cy=header-username]').should(
|
||||
'have.text',
|
||||
defaults.auth.username
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,35 +0,0 @@
|
||||
// / <reference types="Cypress" />
|
||||
|
||||
context('Login', () => {
|
||||
before(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
/* it('OpenNebula logo', () => {
|
||||
|
||||
}); */
|
||||
|
||||
/* it('requires email', () => {
|
||||
cy.get('form').contains('SignIn').click()
|
||||
cy.get('.error-email').should('contain', 'email error')
|
||||
}); */
|
||||
|
||||
/* it('requires password', () => {
|
||||
cy.get('[data-test=email]').type('')
|
||||
cy.get('form').contains('SignIn').click()
|
||||
cy.get('.error-password').should('contain', 'email error')
|
||||
}); */
|
||||
|
||||
/* it('requires valid email and password', () => {
|
||||
|
||||
}); */
|
||||
|
||||
it('navigates to dashboard on successfull login', () => {
|
||||
cy.login();
|
||||
cy.get('[data-cy=header]').should('be.visible');
|
||||
});
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
// / <reference types="Cypress" />
|
||||
|
||||
context('Dashboard', () => {
|
||||
before(() => {
|
||||
cy.visit('/')
|
||||
cy.login()
|
||||
})
|
||||
|
||||
after(() => {
|
||||
cy.logout()
|
||||
})
|
||||
|
||||
it('validate items', () => {
|
||||
|
||||
})
|
||||
})
|
@ -0,0 +1,31 @@
|
||||
// const { internalLog } = require('../../../support/utils')
|
||||
// / <reference types="Cypress" />
|
||||
context('Login', () => {
|
||||
before(() => {
|
||||
cy.goToIndex(__dirname, () => {
|
||||
cy.login()
|
||||
})
|
||||
})
|
||||
|
||||
after(() => {
|
||||
cy.logout()
|
||||
})
|
||||
|
||||
it('has successfull login', () => {
|
||||
cy.getJWT((JWT) => {
|
||||
if (JWT && cy.wrap(JWT).should('exist')) {
|
||||
cy.get('[data-cy=header]').should('be.visible')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('has username on header', () => {
|
||||
cy.get('[data-cy=header-user-button]').click()
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
cy.get('[data-cy=header-username]').should(
|
||||
'have.text',
|
||||
defaults.auth.username
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,218 @@
|
||||
const { createIntercept, waitIntercept } = require('../../../support/utils')
|
||||
const testType = 'Provider'
|
||||
|
||||
const reloadProviderComponent = () => {
|
||||
// for reload the provider react-component this update the provider list
|
||||
cy.navigateMenu('dashboard')
|
||||
}
|
||||
|
||||
const interceptList = {
|
||||
method: 'GET',
|
||||
url: '/provider/list'
|
||||
}
|
||||
const interceptCreate = {
|
||||
method: 'POST',
|
||||
url: '/provider/create'
|
||||
}
|
||||
const interceptConfigure = {
|
||||
method: 'PUT',
|
||||
url: '/provider/update'
|
||||
}
|
||||
const interceptDelete = {
|
||||
method: 'DELETE',
|
||||
url: '/provider/delete'
|
||||
}
|
||||
|
||||
let defaultSettings = {}
|
||||
|
||||
context(testType, () => {
|
||||
before(() => {
|
||||
// fill settings
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
defaultSettings = defaults.provision
|
||||
})
|
||||
|
||||
// go to index app
|
||||
cy.visit('/')
|
||||
cy.login()
|
||||
})
|
||||
|
||||
after(() => {
|
||||
cy.logout()
|
||||
})
|
||||
|
||||
it('Create a Provider', () => {
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
cy.get('[data-cy=create-provider]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
cy.get('[data-cy=select-provision-type]').select(defaultSettings.provision || '')
|
||||
cy.get('[data-cy=select-provider-type]').select(defaultSettings.provider || '')
|
||||
let brk = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 200 })
|
||||
}
|
||||
|
||||
// fill form "Configure Connection" tab
|
||||
const fillFormConfigureConnection = () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.get('[data-cy=form-provider-access_key]').clear().type(defaultSettings.key || '')
|
||||
cy.get('[data-cy=form-provider-secret_key]').clear().type(defaultSettings.secretKey || '')
|
||||
const intercept = createIntercept(interceptCreate)
|
||||
cy.wrap($button).click({ force: true })
|
||||
waitIntercept(intercept, validateTest)
|
||||
})
|
||||
}
|
||||
|
||||
// fill form "Provider Overview" tab
|
||||
const fillFormProviderOverview = () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.get('[data-cy=form-provider-name]').clear().type(defaultSettings.nameProvider || '')
|
||||
cy.get('[data-cy=form-provider-description]').clear().type(defaultSettings.descriptionProvider || '')
|
||||
cy.wrap($button).click({ force: true })
|
||||
fillFormConfigureConnection()
|
||||
})
|
||||
}
|
||||
|
||||
// select template in "Provider template" tab
|
||||
const selectTemplate = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('>button').click({ force: true }).then(() => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.wrap($button).click({ force: true })
|
||||
fillFormProviderOverview()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider template in "Provider template" tab
|
||||
cy.get('[data-cy=providers-templates]').find('[data-cy=provider-template-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvider && $el.find('[data-cy=provider-template-card-title]').text() === defaultSettings.nameProvider) {
|
||||
selectTemplate($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Check information a Provider', () => {
|
||||
reloadProviderComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
// select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('>button').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), info => {
|
||||
cy.get('[data-cy=provider-name]').should('have.text', defaultSettings.nameProvider)
|
||||
cy.get('[data-cy=provider-description]').should('have.text', defaultSettings.descriptionProvider)
|
||||
cy.get('[data-cy=provider-type]').should('have.text', defaultSettings.provider)
|
||||
cy.get('[data-cy=provider-access_key]').should('have.text', defaultSettings.key)
|
||||
cy.get('[data-cy=provider-secret_key]').should('have.text', defaultSettings.secretKey)
|
||||
cy.get('[data-cy=dg-cancel-button]').click({ force: true })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider
|
||||
cy.get('[data-cy=providers]').find('[data-cy=provider-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvider && $el.find('[data-cy=provider-card-title]').text() === defaultSettings.nameProvider) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Configure', () => {
|
||||
reloadProviderComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 200 })
|
||||
}
|
||||
|
||||
// fill "Configure connection" tab
|
||||
const fillConfigureConnection = $button => {
|
||||
const intercept = createIntercept(interceptConfigure)
|
||||
cy.get('[data-cy=form-provider-access_key]').clear().type(defaultSettings.keyEdited || '')
|
||||
cy.get('[data-cy=form-provider-secret_key]').clear().type(defaultSettings.secretKeyEdited || '')
|
||||
cy.wrap($button).click({ force: true })
|
||||
waitIntercept(intercept, validateTest)
|
||||
}
|
||||
|
||||
// fill "Provider overview" tab
|
||||
const fillProviderOverview = $button => {
|
||||
cy.get('[data-cy=form-provider-description]').clear().type(defaultSettings.descriptionProviderEdited || '')
|
||||
cy.wrap($button).click({ force: true })
|
||||
cy.get('[data-cy=stepper-next-button]').then(fillConfigureConnection)
|
||||
}
|
||||
|
||||
// select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('[data-cy=provider-edit]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then(fillProviderOverview)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider
|
||||
cy.get('[data-cy=providers]').find('[data-cy=provider-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvider && $el.find('[data-cy=provider-card-title]').text() === defaultSettings.nameProvider) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Delete', () => {
|
||||
reloadProviderComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 202 })
|
||||
}
|
||||
|
||||
// select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('[data-cy=provider-delete]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
const intercept = createIntercept(interceptDelete)
|
||||
cy.get('[data-cy=dg-accept-button]').click({ force: true }).then(() => {
|
||||
waitIntercept(intercept, validateTest)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider
|
||||
cy.get('[data-cy=providers]').find('[data-cy=provider-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvider && $el.find('[data-cy=provider-card-title]').text() === defaultSettings.nameProvider) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,221 @@
|
||||
const { createIntercept, waitIntercept } = require('../../../support/utils')
|
||||
const testType = 'Provision'
|
||||
|
||||
const reloadProvisionComponent = () => {
|
||||
// for reload the provision react-component this update the provider list
|
||||
cy.navigateMenu('dashboard')
|
||||
}
|
||||
|
||||
const interceptProviderList = {
|
||||
method: 'GET',
|
||||
url: '/provider/list'
|
||||
}
|
||||
const interceptList = {
|
||||
method: 'GET',
|
||||
url: '/provision/list'
|
||||
}
|
||||
const interceptCreate = {
|
||||
method: 'POST',
|
||||
url: '/provision/create'
|
||||
}
|
||||
const interceptConfigure = {
|
||||
method: 'PUT',
|
||||
url: '/provision/configure'
|
||||
}
|
||||
const interceptDelete = {
|
||||
method: 'DELETE',
|
||||
url: '/provision/delete'
|
||||
}
|
||||
let defaultSettings = {}
|
||||
|
||||
context(testType, () => {
|
||||
before(() => {
|
||||
// fill settings
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
defaultSettings = defaults.provision
|
||||
})
|
||||
|
||||
//go to index app
|
||||
cy.visit('/')
|
||||
cy.login()
|
||||
})
|
||||
|
||||
after(() => {
|
||||
cy.logout()
|
||||
})
|
||||
|
||||
it('Create', () => {
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
cy.get('[data-cy=create-provision]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptProviderList), () => {
|
||||
cy.get('[data-cy=select-provision-type]').select(defaultSettings.provision || '')
|
||||
cy.get('[data-cy=select-provider-type]').select(defaultSettings.provider || '')
|
||||
let brkProvisionTemplate = true
|
||||
let brkProvider = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 202 })
|
||||
}
|
||||
|
||||
// fill form "Configure inputs" tab
|
||||
const fillFormConfigureInputs = () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.get('[data-cy=form-provision-number_hosts]').clear().type(defaultSettings.numberInstances || '')
|
||||
const intercept = createIntercept(interceptCreate)
|
||||
cy.wrap($button).click({ force: true })
|
||||
waitIntercept(intercept, validateTest)
|
||||
})
|
||||
}
|
||||
|
||||
// fill form "Provider overview" tab
|
||||
const fillFormProvision = () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.get('[data-cy=form-provision-name]').clear().type(defaultSettings.nameProvision || '')
|
||||
cy.get('[data-cy=form-provision-description]').clear().type(defaultSettings.descriptionProvision || '')
|
||||
cy.wrap($button).click({ force: true })
|
||||
fillFormConfigureInputs()
|
||||
})
|
||||
}
|
||||
|
||||
// find provider in "Provider" tab
|
||||
const selectProvider = $el => {
|
||||
brkProvider = false
|
||||
cy.wrap($el).find('>button').click({ force: true }).then(() => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.wrap($button).click({ force: true })
|
||||
fillFormProvision()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider in "Provider" tab
|
||||
const findProvider = () => {
|
||||
cy.get('[data-cy=stepper-next-button]').then($button => {
|
||||
cy.wrap($button).click({ force: true })
|
||||
cy.get('[data-cy=providers]').find('[data-cy=provider-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvision && $el.find('[data-cy=provider-card-title]').text().includes(defaultSettings.nameProvider)) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brkProvider
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// select provision template in "Provision template" tab
|
||||
const selectProvisionTemplate = $el => {
|
||||
brkProvisionTemplate = false
|
||||
cy.wrap($el).find('>button').click({ force: true }).then(findProvider)
|
||||
}
|
||||
|
||||
// find provision template in "Provision template" tab
|
||||
cy.get('[data-cy=provisions-templates]').find('[data-cy=provision-template-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvision && $el.find('[data-cy=provision-template-card-title]').text() === defaultSettings.nameProvision) {
|
||||
selectProvisionTemplate($el)
|
||||
}
|
||||
return brkProvisionTemplate
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Check information', () => {
|
||||
reloadProvisionComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
//select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('>button').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), info => {
|
||||
cy.get('[data-cy=provision-name]').should('have.text', defaultSettings.nameProvision)
|
||||
cy.get('[data-cy=provision-description]').should('have.text', defaultSettings.descriptionProvision)
|
||||
cy.get('[data-cy=provider-provider-name]').should('have.text', defaultSettings.nameProvider)
|
||||
cy.get('[data-cy=provider-cluster]').should('contain', defaultSettings.nameProvision)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//find provider
|
||||
cy.get('[data-cy=provisions]').find('[data-cy=provision-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvider && $el.find('[data-cy=provision-card-title]').text() === defaultSettings.nameProvision) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Configure', () => {
|
||||
reloadProvisionComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 202})
|
||||
}
|
||||
|
||||
// select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('[data-cy=provision-configure]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptConfigure), validateTest)
|
||||
})
|
||||
}
|
||||
|
||||
// find provider
|
||||
cy.get('[data-cy=provisions]').find('[data-cy=provision-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvision && $el.find('[data-cy=provision-card-title]').text() === defaultSettings.nameProvision) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Delete', () => {
|
||||
reloadProvisionComponent()
|
||||
cy.navigateMenu(`${testType}s`, () => {
|
||||
waitIntercept(createIntercept(interceptList), () => {
|
||||
let brk = true
|
||||
|
||||
// expect test
|
||||
const validateTest = request => {
|
||||
expect(request).to.be.a('object')
|
||||
expect(request).to.nested.include({ 'response.body.id': 202})
|
||||
}
|
||||
|
||||
// select provider
|
||||
const selectProvider = $el => {
|
||||
brk = false
|
||||
cy.wrap($el).find('[data-cy=provision-delete]').click({ force: true }).then(() => {
|
||||
waitIntercept(createIntercept(interceptList), ()=>{
|
||||
const intercept = createIntercept(interceptDelete)
|
||||
cy.get('[data-cy=dg-accept-button]').click({force:true}).then(()=>{
|
||||
waitIntercept(intercept, validateTest)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find provider
|
||||
cy.get('[data-cy=provisions]').find('[data-cy=provision-card]').each($el => {
|
||||
if (defaultSettings && defaultSettings.nameProvision && $el.find('[data-cy=provision-card-title]').text() === defaultSettings.nameProvision) {
|
||||
selectProvider($el)
|
||||
}
|
||||
return brk
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
@ -1,31 +1,89 @@
|
||||
const { internalLog } = require('./utils')
|
||||
const { sep } = require('path')
|
||||
|
||||
Cypress.Commands.add('login', () => {
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
cy.get('[data-cy=login-username]').type(defaults.auth.username);
|
||||
cy.get('[data-cy=login-password]').type(defaults.auth.password);
|
||||
});
|
||||
cy.get('[data-cy=login-user]').clear().type(defaults.auth.username)
|
||||
cy.get('[data-cy=login-token]').clear().type(defaults.auth.password)
|
||||
})
|
||||
cy.get('[data-cy=login-button]').then(($btn) => {
|
||||
cy.wrap($btn).click()
|
||||
})
|
||||
})
|
||||
|
||||
cy.get('[data-cy=login-button]').click();
|
||||
});
|
||||
Cypress.Commands.add('openUserModal', (callback = () => undefined) => {
|
||||
cy.get('[data-cy=header-user-button]').then(($btn) => {
|
||||
if ($btn) {
|
||||
cy.wrap($btn).click({ force: true })
|
||||
}
|
||||
callback()
|
||||
})
|
||||
})
|
||||
|
||||
Cypress.Commands.add('logout', () => {
|
||||
cy.get('[data-cy=header-user-button]').click();
|
||||
cy.get('[data-cy=header-logout-button]').click();
|
||||
// cy.fixture('defaults').then(defaults => {
|
||||
// cy.window()
|
||||
// .its('sessionStorage')
|
||||
// .invoke('removeItem', defaults.auth.jwtName);
|
||||
// });
|
||||
});
|
||||
cy.openUserModal(
|
||||
() => {
|
||||
cy.get('[data-cy=header-logout-button]').then(($btn) => {
|
||||
if ($btn) {
|
||||
cy.wrap($btn).click({ force: true })
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
cy.window().its('sessionStorage').invoke('removeItem', defaults.auth.jwtName)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
Cypress.Commands.add('getJWT', (callback = () => undefined) => {
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
cy.window().then(win => {
|
||||
callback(win.sessionStorage.getItem(defaults.auth.jwtName))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Cypress.Commands.add('navigateMenu', (contentText = '', callback = () => undefined) => {
|
||||
if (contentText) {
|
||||
let rtn = true
|
||||
cy.get('[data-cy=main-menu]').find('li').each($li => {
|
||||
if ($li && $li.text && typeof $li.text === 'function' && $li.text().toLowerCase() === contentText.toLowerCase()) {
|
||||
rtn = false
|
||||
cy.wrap($li).click({ force: true }).then(() => {
|
||||
callback()
|
||||
})
|
||||
}
|
||||
return rtn
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.Commands.add('goToIndex', (path = '', callback = () => undefined) => {
|
||||
if (expect(path).to.not.be.empty) {
|
||||
const folders = path.split(sep)
|
||||
cy.fixture('defaults').then(defaults => {
|
||||
if (expect(defaults.apps).to.be.a('object')) {
|
||||
const apps = Object.keys(defaults.apps)
|
||||
let selectApp = ''
|
||||
apps.forEach(app => {
|
||||
if (folders.includes(app)) {
|
||||
selectApp = app
|
||||
}
|
||||
})
|
||||
if (expect(apps).to.be.a('array') && expect(apps).to.include(selectApp)) {
|
||||
cy.visit(`/${selectApp}`, { timeout: 30000 })
|
||||
cy.getJWT((JWT) => {
|
||||
if (!JWT) {
|
||||
cy.get('[data-cy=opennebula-logo]').then($window => {
|
||||
if ($window) {
|
||||
cy.wait(1500)
|
||||
}
|
||||
})
|
||||
}
|
||||
callback()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
41
src/fireedge/cypress/support/utils.js
Normal file
41
src/fireedge/cypress/support/utils.js
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
const { v4 } = require('uuid')
|
||||
|
||||
const createIntercept = (data = {}) => {
|
||||
const uuidv4 = v4()
|
||||
cy.intercept({
|
||||
method: data.method || 'GET',
|
||||
url: data.url || ''
|
||||
}).as(uuidv4)
|
||||
return uuidv4
|
||||
}
|
||||
|
||||
const waitIntercept = (intercept = '', callback = () => undefined) => {
|
||||
if (intercept) {
|
||||
cy.wait(`@${intercept}`).then(interception => {
|
||||
if (interception && interception.state && interception.state === 'Complete' && typeof callback === 'function') {
|
||||
callback(interception)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const internalLog = (command = '', message = '') => {
|
||||
Cypress.log({
|
||||
name: command,
|
||||
displayName: command,
|
||||
consoleProps: () => {
|
||||
return {
|
||||
error: message
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const utils = {
|
||||
internalLog,
|
||||
createIntercept,
|
||||
waitIntercept
|
||||
}
|
||||
|
||||
module.exports = utils
|
473
src/fireedge/package-lock.json
generated
473
src/fireedge/package-lock.json
generated
@ -1176,18 +1176,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@ -1793,9 +1793,9 @@
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"arch": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz",
|
||||
"integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
|
||||
"integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
@ -2005,9 +2005,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
|
||||
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
@ -3305,9 +3305,9 @@
|
||||
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk="
|
||||
},
|
||||
"cypress": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-5.4.0.tgz",
|
||||
"integrity": "sha512-BJR+u3DRSYMqaBS1a3l1rbh5AkMRHugbxcYYzkl+xYlO6dzcJVE8uAhghzVI/hxijCyBg1iuSe4TRp/g1PUg8Q==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-6.2.1.tgz",
|
||||
"integrity": "sha512-OYkSgzA4J4Q7eMjZvNf5qWpBLR4RXrkqjL3UZ1UzGGLAskO0nFTi/RomNTG6TKvL3Zp4tw4zFY1gp5MtmkCZrA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cypress/listr-verbose-renderer": "^0.4.1",
|
||||
@ -3322,7 +3322,7 @@
|
||||
"chalk": "^4.1.0",
|
||||
"check-more-types": "^2.24.0",
|
||||
"cli-table3": "~0.6.0",
|
||||
"commander": "^4.1.1",
|
||||
"commander": "^5.1.0",
|
||||
"common-tags": "^1.8.0",
|
||||
"debug": "^4.1.1",
|
||||
"eventemitter2": "^6.4.2",
|
||||
@ -3340,10 +3340,10 @@
|
||||
"minimist": "^1.2.5",
|
||||
"moment": "^2.27.0",
|
||||
"ospath": "^1.2.2",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"pretty-bytes": "^5.4.1",
|
||||
"ramda": "~0.26.1",
|
||||
"request-progress": "^3.0.0",
|
||||
"supports-color": "^7.1.0",
|
||||
"supports-color": "^7.2.0",
|
||||
"tmp": "~0.2.1",
|
||||
"untildify": "^4.0.0",
|
||||
"url": "^0.11.0",
|
||||
@ -3384,10 +3384,16 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
|
||||
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
@ -3506,6 +3512,12 @@
|
||||
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
|
||||
"dev": true
|
||||
},
|
||||
"dateformat": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||
"integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"debounce": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
|
||||
@ -3633,6 +3645,12 @@
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
},
|
||||
"diff-match-patch": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
|
||||
@ -4595,9 +4613,9 @@
|
||||
}
|
||||
},
|
||||
"execa": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
|
||||
"integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
|
||||
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
@ -5206,6 +5224,12 @@
|
||||
"nan": "^2.12.1"
|
||||
}
|
||||
},
|
||||
"fsu": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz",
|
||||
"integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==",
|
||||
"dev": true
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
@ -5334,12 +5358,20 @@
|
||||
}
|
||||
},
|
||||
"global-dirs": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
|
||||
"integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
|
||||
"integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ini": "^1.3.5"
|
||||
"ini": "1.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"ini": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
|
||||
"integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"global-modules": {
|
||||
@ -5626,7 +5658,8 @@
|
||||
"html-entities": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
|
||||
"integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA=="
|
||||
"integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
|
||||
"dev": true
|
||||
},
|
||||
"http": {
|
||||
"version": "0.0.1-security",
|
||||
@ -6620,11 +6653,23 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
|
||||
},
|
||||
"lodash.isempty": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
|
||||
"integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||
},
|
||||
"lodash.isfunction": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
||||
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
@ -6635,6 +6680,12 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
|
||||
},
|
||||
"lodash.isobject": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz",
|
||||
"integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
@ -7094,6 +7145,337 @@
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
||||
},
|
||||
"mochawesome": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-6.2.1.tgz",
|
||||
"integrity": "sha512-zew/N1Gb4JYCTl3scu9i8OW0ay7b0ZOGczCrSW/P+XdBrLntqI5/JlJiYV1/Nn/SY4qahddsIE+qWL8ACNerPA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.0.0",
|
||||
"diff": "^4.0.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"lodash.isempty": "^4.4.0",
|
||||
"lodash.isfunction": "^3.0.9",
|
||||
"lodash.isobject": "^3.0.2",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"mochawesome-report-generator": "^5.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"uuid": "^7.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
|
||||
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mochawesome-merge": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mochawesome-merge/-/mochawesome-merge-4.2.0.tgz",
|
||||
"integrity": "sha512-FSMzagh+8hTShhFXdBLE4/zS2WALcDruoD0bmtiwHEjfyQszR/iEGFTgbuM5ewA5At3qeSGwGsT0k2Stt64NdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs-extra": "^7.0.1",
|
||||
"glob": "^7.1.6",
|
||||
"uuid": "^3.3.2",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mochawesome-report-generator": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-5.1.0.tgz",
|
||||
"integrity": "sha512-5cI4Jh+sD+jIxc7q94961vnm/6VKDI7TFUPt9dps6oAc4y4WMpEeeOlmgKKM81q2eGaviNUYw+acFalGK6EJ9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"dateformat": "^3.0.2",
|
||||
"escape-html": "^1.0.3",
|
||||
"fs-extra": "^7.0.0",
|
||||
"fsu": "^1.0.2",
|
||||
"lodash.isfunction": "^3.0.8",
|
||||
"opener": "^1.4.2",
|
||||
"prop-types": "^15.7.2",
|
||||
"tcomb": "^3.2.17",
|
||||
"tcomb-validation": "^3.3.0",
|
||||
"validator": "^10.11.0",
|
||||
"yargs": "^13.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
@ -7644,6 +8026,12 @@
|
||||
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
|
||||
"dev": true
|
||||
},
|
||||
"opener": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
||||
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
|
||||
"dev": true
|
||||
},
|
||||
"optionator": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||
@ -7950,9 +8338,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"pretty-bytes": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
|
||||
"integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz",
|
||||
"integrity": "sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA==",
|
||||
"dev": true
|
||||
},
|
||||
"process": {
|
||||
@ -9667,6 +10055,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcomb": {
|
||||
"version": "3.2.29",
|
||||
"resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz",
|
||||
"integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tcomb-validation": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz",
|
||||
"integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tcomb": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||
@ -10197,6 +10600,12 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"validator": {
|
||||
"version": "10.11.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
|
||||
"integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==",
|
||||
"dev": true
|
||||
},
|
||||
"value-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||
|
@ -10,7 +10,7 @@
|
||||
"build": "npm run build-front && npm run build-server",
|
||||
"start": "cross-env NODE_ENV=production babel-node ./dist/index.js",
|
||||
"cypress:open": "cypress open",
|
||||
"cypress:run": "cypress run --headless --browser chrome --spec \"cypress/integration/**/*.spec.js\"",
|
||||
"cypress:run": "rimraf cypress/results/* && node cypress/command/index.js",
|
||||
"pot": "node potfile.js",
|
||||
"po2json": "node po2json.js",
|
||||
"lint": "eslint ./src/client/",
|
||||
@ -42,6 +42,9 @@
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"fireedge-genpotfile": "^1.0.0",
|
||||
"fireedge-pojson": "^1.0.2",
|
||||
"mochawesome": "^6.2.1",
|
||||
"mochawesome-merge": "^4.2.0",
|
||||
"mochawesome-report-generator": "^5.1.0",
|
||||
"react-hot-loader": "^4.13.0",
|
||||
"webpack-dev-middleware": "^3.7.2",
|
||||
"webpack-hot-middleware": "^2.25.0"
|
||||
@ -129,4 +132,4 @@
|
||||
"yup": "^0.29.3",
|
||||
"zeromq": "^5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ const ProvisionCard = memo(
|
||||
const imgSource = useMemo(() => (
|
||||
isExternalURL(image) ? image : `${IMAGES_URL}/${image}`
|
||||
), [image])
|
||||
|
||||
const dataCy = isProvider ? 'provider' : 'provision'
|
||||
return (
|
||||
<SelectCard
|
||||
title={NAME}
|
||||
@ -54,6 +54,8 @@ const ProvisionCard = memo(
|
||||
</StatusBadge>
|
||||
)
|
||||
}
|
||||
cardProps={{ 'data-cy': `${dataCy}-card` }}
|
||||
cardHeaderProps={{ titleTypographyProps: { 'data-cy': `${dataCy}-card-title` } }}
|
||||
mediaProps={{
|
||||
component: 'img',
|
||||
image: imgSource,
|
||||
|
@ -24,7 +24,7 @@ const ProvisionTemplateCard = React.memo(
|
||||
const imgSource = React.useMemo(() =>
|
||||
isExternalURL(image) ? image : `${IMAGES_URL}/${image}`
|
||||
, [image])
|
||||
|
||||
const dataCy = isProvider ? 'provider' : 'provision'
|
||||
return (
|
||||
<SelectCard
|
||||
title={name}
|
||||
@ -38,6 +38,8 @@ const ProvisionTemplateCard = React.memo(
|
||||
draggable: false,
|
||||
onError
|
||||
}}
|
||||
cardProps={{ 'data-cy': `${dataCy}-template-card` }}
|
||||
cardHeaderProps={{ titleTypographyProps: { 'data-cy': `${dataCy}-template-card-title` } }}
|
||||
/>
|
||||
)
|
||||
},
|
||||
|
@ -86,7 +86,7 @@ const CustomStepper = ({
|
||||
))}
|
||||
</Stepper>
|
||||
<Box marginY={2} textAlign='end'>
|
||||
<Button onClick={handleBack} disabled={disabledBack}>
|
||||
<Button onClick={handleBack} disabled={disabledBack} data-cy='stepper-back-button'>
|
||||
{Tr(T.Back)}
|
||||
</Button>
|
||||
<SubmitButton
|
||||
|
@ -21,7 +21,8 @@ const ListCards = ({
|
||||
cardsProps,
|
||||
EmptyComponent,
|
||||
displayEmpty,
|
||||
isLoading
|
||||
isLoading,
|
||||
gridProps
|
||||
}) => {
|
||||
const classes = listCardsStyles()
|
||||
const isMobile = useMediaQuery(theme => theme.breakpoints.only('xs'))
|
||||
@ -31,7 +32,7 @@ const ListCards = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid container spacing={3} {...gridProps}>
|
||||
{/* CREATE CARD COMPONENT */}
|
||||
{handleCreate && (ButtonCreateComponent ? (
|
||||
<ButtonCreateComponent onClick={handleCreate} />
|
||||
@ -110,7 +111,10 @@ ListCards.propTypes = {
|
||||
PropTypes.element
|
||||
]),
|
||||
displayEmpty: PropTypes.bool,
|
||||
isLoading: PropTypes.bool
|
||||
isLoading: PropTypes.bool,
|
||||
gridProps: PropTypes.shape({
|
||||
'data-cy': PropTypes.string
|
||||
})
|
||||
}
|
||||
|
||||
ListCards.defaultProps = {
|
||||
@ -123,7 +127,8 @@ ListCards.defaultProps = {
|
||||
cardsProps: () => undefined,
|
||||
EmptyComponent: undefined,
|
||||
displayEmpty: false,
|
||||
isLoading: false
|
||||
isLoading: false,
|
||||
gridProps: {}
|
||||
}
|
||||
|
||||
ListCards.displayName = 'ListCards'
|
||||
|
@ -80,7 +80,7 @@ const Template = () => ({
|
||||
<Breadcrumbs separator={<ArrowIcon color="secondary" />}>
|
||||
<Select
|
||||
color='secondary'
|
||||
data-cy='select-provision-type'
|
||||
inputProps = {{ 'data-cy': 'select-provision-type' }}
|
||||
native
|
||||
style={{ minWidth: '8em' }}
|
||||
onChange={handleChangeProvision}
|
||||
@ -92,7 +92,7 @@ const Template = () => ({
|
||||
</Select>
|
||||
{provisionSelected && <Select
|
||||
color='secondary'
|
||||
data-cy='select-provider-type'
|
||||
inputProps = {{ 'data-cy': 'select-provider-type' }}
|
||||
native
|
||||
style={{ minWidth: '8em' }}
|
||||
onChange={handleChangeProvider}
|
||||
@ -124,6 +124,7 @@ const Template = () => ({
|
||||
: 'Your providers templates list is empty'
|
||||
} />
|
||||
}
|
||||
gridProps={{ 'data-cy': 'providers-templates' }}
|
||||
CardComponent={ProvisionTemplateCard}
|
||||
cardsProps={({ value = {} }) => {
|
||||
const isSelected = data?.some(selected =>
|
||||
|
@ -37,15 +37,15 @@ const Info = memo(({ data }) => {
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Name)}</Typography>
|
||||
<Typography>{NAME}</Typography>
|
||||
<Typography data-cy="provider-name">{NAME}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Description)}</Typography>
|
||||
<Typography noWrap>{description}</Typography>
|
||||
<Typography data-cy="provider-description" noWrap>{description}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Provider)}</Typography>
|
||||
<Typography>{providerName}</Typography>
|
||||
<Typography data-cy="provider-type">{providerName}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.RegistrationTime)}</Typography>
|
||||
@ -57,7 +57,7 @@ const Info = memo(({ data }) => {
|
||||
typeof value === 'string' && (
|
||||
<ListItem key={key}>
|
||||
<Typography>{key}</Typography>
|
||||
<Typography>{value}</Typography>
|
||||
<Typography data-cy={`provider-${key}`}>{value}</Typography>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
|
@ -39,7 +39,7 @@ function Providers () {
|
||||
onClick: () => fetchRequest(undefined, { reload: true }),
|
||||
isSubmitting: Boolean(loading || reloading)
|
||||
}}
|
||||
addButtonProps={{ onClick: () => history.push(PATH.PROVIDERS.CREATE) }}
|
||||
addButtonProps={{ 'data-cy': 'create-provider', onClick: () => history.push(PATH.PROVIDERS.CREATE) }}
|
||||
searchProps={{ handleChange }}
|
||||
/>
|
||||
<Box p={3}>
|
||||
@ -49,6 +49,7 @@ function Providers () {
|
||||
<ListCards
|
||||
list={result ?? providers}
|
||||
isLoading={providers.length === 0 && loading}
|
||||
gridProps={{ 'data-cy': 'providers' }}
|
||||
CardComponent={ProvisionCard}
|
||||
cardsProps={({ value: { ID, NAME } }) => ({
|
||||
isProvider: true,
|
||||
@ -62,7 +63,7 @@ function Providers () {
|
||||
handleClick: () =>
|
||||
history.push(PATH.PROVIDERS.EDIT.replace(':id', ID)),
|
||||
icon: <EditIcon />,
|
||||
cy: `provider-edit-${ID}`
|
||||
cy: 'provider-edit'
|
||||
},
|
||||
{
|
||||
handleClick: () => setShowDialog({
|
||||
@ -74,7 +75,7 @@ function Providers () {
|
||||
}
|
||||
}),
|
||||
icon: <DeleteIcon color='error' />,
|
||||
cy: `provider-delete-${ID}`
|
||||
cy: 'provider-delete'
|
||||
}
|
||||
]
|
||||
})}
|
||||
|
@ -43,19 +43,19 @@ const Info = memo(({ data }) => {
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Name)}</Typography>
|
||||
<Typography>{name}</Typography>
|
||||
<Typography data-cy="provision-name">{name}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Description)}</Typography>
|
||||
<Typography noWrap>{description}</Typography>
|
||||
<Typography data-cy="provision-description" noWrap>{description}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Provider)}</Typography>
|
||||
<Typography>{providerName}</Typography>
|
||||
<Typography data-cy="provider-provider-name">{providerName}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.Cluster)}</Typography>
|
||||
<Typography>{`${clusterId} - ${clusterName}`}</Typography>
|
||||
<Typography data-cy="provider-cluster">{`${clusterId} - ${clusterName}`}</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>{Tr(T.StartTime)}</Typography>
|
||||
|
@ -50,6 +50,7 @@ const Provider = () => ({
|
||||
list={providersByTypeAndService}
|
||||
EmptyComponent={<EmptyCard title={'Your providers list is empty'} />}
|
||||
CardComponent={ProvisionCard}
|
||||
gridProps={{ 'data-cy': 'providers' }}
|
||||
cardsProps={({ value: { ID } }) => {
|
||||
const isSelected = data?.some(selected => selected === ID)
|
||||
|
||||
|
@ -87,7 +87,7 @@ const Template = () => ({
|
||||
<Breadcrumbs separator={<ArrowIcon color="secondary" />}>
|
||||
<Select
|
||||
color='secondary'
|
||||
data-cy='select-provision-type'
|
||||
inputProps = {{ 'data-cy': 'select-provision-type' }}
|
||||
native
|
||||
style={{ minWidth: '8em' }}
|
||||
onChange={handleChangeProvision}
|
||||
@ -99,7 +99,7 @@ const Template = () => ({
|
||||
</Select>
|
||||
{provisionSelected && <Select
|
||||
color='secondary'
|
||||
data-cy='select-provider-type'
|
||||
inputProps = {{ 'data-cy': 'select-provider-type' }}
|
||||
native
|
||||
style={{ minWidth: '8em' }}
|
||||
onChange={handleChangeProvider}
|
||||
@ -131,6 +131,7 @@ const Template = () => ({
|
||||
: 'Your provisions templates list is empty'
|
||||
} />
|
||||
}
|
||||
gridProps={{ 'data-cy': 'provisions-templates' }}
|
||||
CardComponent={ProvisionTemplateCard}
|
||||
cardsProps={({ value = {} }) => {
|
||||
const isSelected = data?.some(selected =>
|
||||
|
@ -45,7 +45,7 @@ function Provisions () {
|
||||
onClick: () => fetchRequest(undefined, { reload: true }),
|
||||
isSubmitting: Boolean(loading || reloading)
|
||||
}}
|
||||
addButtonProps={{ onClick: () => history.push(PATH.PROVISIONS.CREATE) }}
|
||||
addButtonProps={{ 'data-cy': 'create-provision', onClick: () => history.push(PATH.PROVISIONS.CREATE) }}
|
||||
searchProps={{ handleChange }}
|
||||
/>
|
||||
<Box p={3}>
|
||||
@ -55,6 +55,7 @@ function Provisions () {
|
||||
<ListCards
|
||||
list={result ?? provisions}
|
||||
isLoading={provisions.length === 0 && loading}
|
||||
gridProps={{ 'data-cy': 'provisions' }}
|
||||
CardComponent={ProvisionCard}
|
||||
cardsProps={({ value: { ID, NAME } }) => ({
|
||||
handleClick: () => setShowDialog({
|
||||
@ -67,7 +68,7 @@ function Provisions () {
|
||||
{
|
||||
handleClick: () => configureProvision({ id: ID }),
|
||||
icon: <EditIcon />,
|
||||
cy: `provision-configure-${ID}`
|
||||
cy: 'provision-configure'
|
||||
},
|
||||
{
|
||||
handleClick: () => setShowDialog({
|
||||
@ -80,7 +81,7 @@ function Provisions () {
|
||||
content: DialogInfo
|
||||
}),
|
||||
icon: <DeleteIcon color='error' />,
|
||||
cy: `provision-delete-${ID}`
|
||||
cy: 'provision-delete'
|
||||
}
|
||||
]
|
||||
})}
|
||||
|
Loading…
x
Reference in New Issue
Block a user