Skip to content

Commit 767e3dd

Browse files
committed
feat(python_snippets#Get the attribute of an attribute): Get the attribute of an attribute when sorting
To sort the list in place: ```python ut.sort(key=lambda x: x.count, reverse=True) ``` To return a new list, use the `sorted()` built-in function: ```python newlist = sorted(ut, key=lambda x: x.body.id_, reverse=True) ``` feat(cypress): Add Cypress commands For the functions you write a lot you can use commands in `/cypress/support/commands.ts`. ```javascript 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 ```javascript cy.getById('submit') ``` feat(cypress#Select by position in list): 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. ```javascript 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. ```javascript cy .get('li') .filter('.primary') // select all elements with the class .primary ``` To do the exact opposite, you can use `.not()` command. ```javascript cy .get('li') .not('.primary') // select all elements without the class .primary ``` feat(cypress#Finding elements): 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. ```javascript 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. ```javascript cy .get('.violet') .parent('.list') // finds an element with class .list that is above our .violet element ``` feat(cypress#Asserting about elements): Assert on the content of an attribute ```javascript cy .get('a') .invoke('attr', 'href') .should('eq', 'https://docs.cypress.io') ``` feat(cypress#Use the content of a fixture set in a hook in a test): 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. ```javascript 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') }) }) ``` feat(cypress#issues): Run only failing tests Cypress doesn't [Allow to rerun failed tests](cypress-io/cypress#4886) but you can use `it.only` on the test you want to run. feat(vuejs#Make HTTP requests): Make HTTP requests with Vue Compare [Fetch API](vuejs.md#fetch-api) and [Axios](vuejs.md#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](https://medium.com/bb-tutorials-and-thoughts/how-to-make-api-calls-in-vue-js-applications-43e017d4dc86). * 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: * [How To Make API calls in Vue.JS Applications by Bhargav Bachina](https://medium.com/bb-tutorials-and-thoughts/how-to-make-api-calls-in-vue-js-applications-43e017d4dc86) * [Axios vs. fetch(): Which is best for making HTTP requests? by Faraz Kelhini](https://blog.logrocket.com/axios-vs-fetch-best-http-requests/)
1 parent 255ad8b commit 767e3dd

File tree

6 files changed

+754
-7
lines changed

6 files changed

+754
-7
lines changed

docs/coding/javascript/javascript.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,8 @@ for (var i = 0; i < a.length; i++) {
376376
377377
### Append an item to an array
378378
379-
Although `push()` could be used, is better to use `concat()` as it doesn't
380-
mutate the original array.
379+
If you want to alter the original array use `push()` although, it's better to
380+
use `concat()` as it doesn't mutate the original array.
381381
382382
```javascript
383383
a.concat(item);

docs/coding/python/python_snippets.md

+15
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,21 @@ tuples of field and order to sort them on multiple passes.
703703
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
704704
```
705705

706+
## [Get the attribute of an attribute](https://stackoverflow.com/questions/403421/how-to-sort-a-list-of-objects-based-on-an-attribute-of-the-objects)
707+
708+
To sort the list in place:
709+
710+
```python
711+
ut.sort(key=lambda x: x.count, reverse=True)
712+
```
713+
714+
To return a new list, use the `sorted()` built-in function:
715+
716+
```python
717+
newlist = sorted(ut, key=lambda x: x.body.id_, reverse=True)
718+
```
719+
720+
706721
# [Iterate over an instance object's data attributes in Python](https://www.saltycrane.com/blog/2008/09/how-iterate-over-instance-objects-data-attributes-python/)
707722

708723
```python

docs/coding/python/type_hints.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def new_user(user_class) -> User:
310310

311311
Where:
312312

313-
* `ProUser` doesnt inherit from `BasicUser`.
313+
* `ProUser` doesn't inherit from `BasicUser`.
314314
* `new_user` creates an instance of one of these classes if you pass
315315
it the right class object.
316316

@@ -343,7 +343,7 @@ beginner.upgrade() # OK
343343
```
344344

345345
!!! note
346-
"Using `UserT` is [not supported by
346+
"Using `UserType` is [not supported by
347347
pylint](https://github.com/PyCQA/pylint/issues/6003), use `UserT`
348348
instead."
349349

docs/cypress.md

+180-3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,28 @@ the `data-cy` element.
197197
cy.get('[data-cy=submit]')
198198
```
199199

200+
You'll probably write that a lot, that's why it's useful to define the next
201+
commands in `/cypress/support/commands.ts`.
202+
203+
```javascript
204+
Cypress.Commands.add('getById', (selector, ...args) => {
205+
return cy.get(`[data-cy=${selector}]`, ...args)
206+
})
207+
208+
Cypress.Commands.add('getByIdLike', (selector, ...args) => {
209+
return cy.get(`[data-cy*=${selector}]`, ...args)
210+
})
211+
212+
Cypress.Commands.add('findById', {prevSubject: true}, (subject, selector, ...args) => {
213+
return subject.find(`[data-cy=${selector}]`, ...args)
214+
})
215+
```
216+
217+
So you can now do
218+
```javascript
219+
cy.getById('submit')
220+
```
221+
200222
### Query by content
201223

202224
Another way to locate things -- a more human way -- is to look them up by their
@@ -226,6 +248,65 @@ timeout.
226248
cy.get('.my-slow-selector', { timeout: 10000 })
227249
```
228250

251+
### Select by position in list
252+
253+
Inside our list, we can select elements based on their position in the list,
254+
using `.first()`, `.last()` or `.eq()` selector.
255+
256+
```javascript
257+
cy
258+
.get('li')
259+
.first(); // select "red"
260+
261+
cy
262+
.get('li')
263+
.last(); // select "violet"
264+
265+
cy
266+
.get('li')
267+
.eq(2); // select "yellow"
268+
```
269+
270+
You can also use `.next()` and `.prev()` to navigate through the elements.
271+
272+
### Select elements by filtering
273+
274+
Once you select multiple elements, you can filter within these based on another selector.
275+
276+
```javascript
277+
cy
278+
.get('li')
279+
.filter('.primary') // select all elements with the class .primary
280+
```
281+
282+
To do the exact opposite, you can use `.not()` command.
283+
284+
cy
285+
.get('li')
286+
.not('.primary') // select all elements without the class .primary
287+
288+
### Finding elements
289+
290+
You can specify your selector by first selecting an element you want to search
291+
within, and then look down the DOM structure to find a specific element you are
292+
looking for.
293+
294+
```javascript
295+
cy
296+
.get('.list')
297+
.find('.violet') // finds an element with class .violet inside .list element
298+
```
299+
300+
Instead of looking down the DOM structure and finding an element within another
301+
element, we can look up. In this example, we first select our list item, and
302+
then try to find an element with a `.list` class.
303+
304+
```javascript
305+
cy
306+
.get('.violet')
307+
.parent('.list') // finds an element with class .list that is above our .violet element
308+
```
309+
229310
## Interacting with elements
230311

231312
Cypress allows you to click on and type into elements on the page by using
@@ -333,8 +414,6 @@ it('utilize users in some way', function () {
333414
})
334415
```
335416

336-
337-
338417
## [Asserting about elements](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Assertions)
339418

340419
Assertions let you do things like ensuring an element is visible or has
@@ -440,6 +519,14 @@ expect(true).to.be.true
440519
cy.get('li.selected').should('have.length', 3)
441520
```
442521

522+
* *Attribute*:
523+
```javascript
524+
// check the content of an attribute
525+
cy
526+
.get('a')
527+
.invoke('attr', 'href')
528+
.should('eq', 'https://docs.cypress.io')
529+
```
443530
* *Class*:
444531

445532
```javascript
@@ -725,7 +812,6 @@ The purpose of a test fixture is to ensure that there is a well known and fixed
725812
environment in which tests are run so that results are repeatable. Fixtures are
726813
accessed within tests by calling the `cy.fixture()` command.
727814

728-
729815
When stubbing a response, you typically need to manage potentially large and
730816
complex JSON objects. Cypress allows you to integrate fixture syntax directly
731817
into responses.
@@ -752,6 +838,32 @@ your `cy.fixture()` command.
752838
cy.fixture('images/dogs.png') // yields dogs.png as Base64
753839
```
754840

841+
#### [Use the content of a fixture set in a hook in a test](https://docs.cypress.io/api/commands/fixture#Encoding)
842+
843+
844+
If you store and access the fixture data using this test context object, make
845+
sure to use `function () { ... }` callbacks both for the hook and the test.
846+
Otherwise the test engine will NOT have this pointing at the test context.
847+
848+
```javascript
849+
describe('User page', () => {
850+
beforeEach(function () {
851+
// "this" points at the test context object
852+
cy.fixture('user').then((user) => {
853+
// "this" is still the test context object
854+
this.user = user
855+
})
856+
})
857+
858+
// the test callback is in "function () { ... }" form
859+
it('has user', function () {
860+
// this.user exists
861+
expect(this.user.firstName).to.equal('Jane')
862+
})
863+
})
864+
```
865+
866+
755867
### Logging in
756868

757869
One of the first (and arguably one of the hardest) hurdles you'll have to
@@ -1084,6 +1196,65 @@ describe('Logo', () => {
10841196
})
10851197
```
10861198

1199+
### Use functions
1200+
1201+
Sometimes, the piece of code is redundant and we don't we don't require it in
1202+
all the test cases. We can create utility functions and move such code there.
1203+
1204+
We can create a separate folder as utils in support folder and store our
1205+
functions in a file in that folder.
1206+
1207+
Consider the following example of utility function for login.
1208+
1209+
```javascript
1210+
//cypress/support/utils/common.js
1211+
1212+
export const loginViaUI = (username, password) => {
1213+
cy.get("[data-cy='login-email-field']").type(username);
1214+
cy.get("[data-cy='login-password-field']").type(password);
1215+
cy.get("[data-cy='submit-button']").submit()
1216+
}
1217+
```
1218+
1219+
This is how we can use utility function in our test case:
1220+
1221+
```javascript
1222+
import {
1223+
loginViaUI
1224+
} from '../support/utils/common.js';
1225+
1226+
describe("Login", () => {
1227+
it('should allow user to log in', () => {
1228+
cy.visit('/login');
1229+
loginViaUI('username', 'password');
1230+
});
1231+
});
1232+
```
1233+
1234+
Utility functions are similar to Cypress commands. If the code being used in
1235+
almost every test suite, we can create a custom command for it. The benefit of
1236+
this is that we don't have to import the js file to use the command, it is
1237+
available directly on cy object i.e. `cy.loginViaUI()`.
1238+
1239+
But, this doesn't mean that we should use commands for everything. If the code
1240+
is used in only some of the test suite, we can create a utility function and
1241+
import it whenever needed.
1242+
1243+
## [Setting up time of the tests](https://docs.cypress.io/api/commands/clock#No-Args)
1244+
1245+
Specify a `now` timestamp
1246+
1247+
```javascript
1248+
// your app code
1249+
$('#date').text(new Date().toJSON())
1250+
1251+
const now = new Date(2017, 3, 14).getTime() // April 14, 2017 timestamp
1252+
1253+
cy.clock(now)
1254+
cy.visit('/index.html')
1255+
cy.get('#date').contains('2017-04-14')
1256+
```
1257+
10871258
## [Component testing](https://docs.cypress.io/guides/component-testing/introduction)
10881259

10891260
Component testing in Cypress is similar to end-to-end testing. The notable differences are:
@@ -1420,6 +1591,12 @@ it('adds items', () => {
14201591
This allows you to inspect the web application, the DOM, the network, and any
14211592
storage after each command to make sure everything happens as expected.
14221593
1594+
# Issues
1595+
1596+
* [Allow rerun only failed
1597+
tests](https://github.com/cypress-io/cypress/issues/4886): Until it's ready
1598+
use `it.only` on the test you want to run.
1599+
14231600
# References
14241601
14251602
* [Home](https://www.cypress.io/)

docs/javascript_snippets.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ date: 20220419
44
author: Lyz
55
---
66

7+
# [Select a substring](https://medium.com/coding-at-dawn/how-to-select-a-range-from-a-string-a-substring-in-javascript-1ba611e7fc1)
8+
9+
```javascript
10+
'long string'.substring(startIndex, endIndex)
11+
```
12+
713
# [Round a number](https://www.w3schools.com/jsref/jsref_round.asp)
814

915
```javascript

0 commit comments

Comments
 (0)