25th April 2022
Coding⚑
-
New: Add Cypress commands.
For the functions you write a lot you can use commands in
/cypress/support/commands.ts
.Cypress.Commands.add('getById', (selector, ...args) => { return cy.get(`[data-cy=${selector}]`, ...args) }) Cypress.Commands.add('getByIdLike', (selector, ...args) => { return cy.get(`[data-cy*=${selector}]`, ...args) }) Cypress.Commands.add('findById', {prevSubject: true}, (subject, selector, ...args) => { return subject.find(`[data-cy=${selector}]`, ...args) })
So you can now do
cy.getById('submit')
-
New: Add more ways to select elements.
- Select by position in list
Inside our list, we can select elements based on their position in the list, using
.first()
,.last()
or.eq()
selector.cy .get('li') .first(); // select "red" cy .get('li') .last(); // select "violet" cy .get('li') .eq(2); // select "yellow"
You can also use
.next()
and.prev()
to navigate through the elements.- Select elements by filtering
Once you select multiple elements, you can filter within these based on another selector.
cy .get('li') .filter('.primary') // select all elements with the class .primary
To do the exact opposite, you can use
.not()
command.cy .get('li') .not('.primary') // select all elements without the class .primary
-
New: Finding elements.
You can specify your selector by first selecting an element you want to search within, and then look down the DOM structure to find a specific element you are looking for.
cy .get('.list') .find('.violet') // finds an element with class .violet inside .list element
Instead of looking down the DOM structure and finding an element within another element, we can look up. In this example, we first select our list item, and then try to find an element with a
.list
class.cy .get('.violet') .parent('.list') // finds an element with class .list that is above our .violet element
-
New: Assert on the content of an attribute.
cy .get('a') .invoke('attr', 'href') .should('eq', 'https://docs.cypress.io')
-
New: Use the content of a fixture set in a hook in a test.
If you store and access the fixture data using this test context object, make sure to use
function () { ... }
callbacks both for the hook and the test. Otherwise the test engine will NOT have this pointing at the test context.describe('User page', () => { beforeEach(function () { // "this" points at the test context object cy.fixture('user').then((user) => { // "this" is still the test context object this.user = user }) }) // the test callback is in "function () { ... }" form it('has user', function () { // this.user exists expect(this.user.firstName).to.equal('Jane') }) })
-
Cypress doesn't Allow to rerun failed tests but you can use
it.only
on the test you want to run. -
New: Make HTTP requests with Vue.
Compare Fetch API and Axios when doing http requests to external services.
Explain how to do them with both methods and arrive to the conclusion that if you’re working on multiple requests, you’ll find that Fetch requires you to write more code than Axios, even when taking into consideration the setup needed for it. Therefore, for simple requests, Fetch API and Axios are quite the same. However, for more complex requests, Axios is better as it allows you to configure multiple requests in one place.
If you're making a simple request use the Fetch API, for the other cases use axios because:
- It allows you to configure multiple requests in one place
- Code is shorter.
- It allows you to place all the API calls under services so that these can be reused across components wherever they are needed.
- It's easy to set a timeout of the request.
- It supports HTTP interceptors by befault
- It does automatic JSON data transformation.
- It's supported by old browsers, although you can bypass the problem with fetch too.
- It has a progress indicator for large files.
- Supports simultaneous requests by default.
Axios provides an easy-to-use API in a compact package for most of your HTTP communication needs. However, if you prefer to stick with native APIs, nothing stops you from implementing Axios features.
For more information read:
-
New: Simulate errors.
context('Errors', () => { const errorMsg = 'Oops! Try again later' it('simulates a server error', () => { cy.intercept( 'GET', '**/search?query=cypress', { statusCode: 500 } ).as('getServerFailure') cy.visit('https://example.com/search') cy.get('[data-cy="search-field"]') .should('be.visible') .type('cypress{enter}') cy.wait('@getServerFailure') cy.contains(errorMsg) .should('be.visible') }) it('simulates a network failure', () => { cy.intercept( 'GET', '**/search?query=cypressio', { forceNetworkError: true } ).as('getNetworkFailure') cy.visit('https://example.com/search') cy.get('[data-cy="search-field"]') .should('be.visible') .type('cypressio{enter}') cy.wait('@getNetworkFailure') cy.contais(errorMsg) .should('be.visible') }) })
-
New: Handling errors doing requests to other endpoints.
To catch errors when doing requests you could use:
try { let res = await axios.get('/my-api-route'); // Work with the response... } catch (error) { if (error.response) { // The client was given an error response (5xx, 4xx) console.log(err.response.data); console.log(err.response.status); console.log(err.response.headers); } else if (error.request) { // The client never received a response, and the request was never left console.log(err.request); } else { // Anything else console.log('Error', err.message); } }
The differences in the
error
object, indicate where the request encountered the issue.-
error.response
: If yourerror
object has aresponse
property, it means that your server returned a 4xx/5xx error. This will assist you choose what sort of message to return to users. -
error.request
: This error is caused by a network error, a hanging backend that does not respond instantly to each request, unauthorized or cross-domain requests, and lastly if the backend API returns an error.This occurs when the browser was able to initiate a request but did not receive a valid answer for any reason.
-
Other errors: It's possible that the
error
object does not have either aresponse
orrequest
object attached to it. In this case it is implied that there was an issue in setting up the request, which eventually triggered an error.For example, this could be the case if you omit the URL parameter from the
.get()
call, and thus no request was ever made.
-
-
New: Use Flexbox with Vuetify.
Control the layout of flex containers with alignment, justification and more with responsive flexbox utilities.
Note
"I suggest you use this page only as a reference, if it's the first time you see this content, it's better to see it at the [source](https://vuetifyjs.com/en/styles/flex) as you can see Flex in action at the same time you read, which makes it much more easy to understand."
Explain how to use:
-
New: Illustrations.
You can get nice illustrations for your web on Drawkit, for example I like to use the Classic kit.
Python⚑
Python Snippets⚑
-
New: Get the attribute of an attribute when sorting.
To sort the list in place:
ut.sort(key=lambda x: x.count, reverse=True)
To return a new list, use the
sorted()
built-in function:newlist = sorted(ut, key=lambda x: x.body.id_, reverse=True)
Other⚑
-
New: Troubleshoot Failed to resolve component: X.
If you've already imported the component with
import X from './X.vue
you may have forgotten to add the component to thecomponents
property of the module:```javascript export default { name: 'Inbox', components: { X } }