Skip to content

17th Week of 2022

Activism

Mentoring

  • New: Introduce the concept and guidelines of mentorship.

    Mentoring is a process for the informal transmission of knowledge, social capital, and the psychosocial support perceived by the recipient as relevant to work, career, or professional development; mentoring entails informal communication, usually face-to-face and during a sustained period of time, between a person who is perceived to have greater relevant knowledge, wisdom, or experience (the mentor) and a person who is perceived to have less (the apprentice).

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')
      })
    })
    
  • New: Run only failing tests.

    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:

    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 your error object has a response 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 a response or request 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.

  • Correction: Correct the way to test for an attribute of an html element.

    cy
     .get('a')
       .should('have.attr', 'href', 'https://docs.cypress.io')
       .and('have.attr', 'target', '_blank') // Test it's meant to be opened
       // another tab
    
  • New: Sending different responses.

    To return different responses from a single GET /todos intercept, you can place all prepared responses into an array, and then use Array.prototype.shift to return and remove the first item.

    it('returns list with more items on page reload', () => {
      const replies = [{ fixture: 'articles.json' }, { statusCode: 404 }]
      cy.intercept('GET', '/api/inbox', req => req.reply(replies.shift()))
    })
    

Learning to code

  • New: Introduce guidelines to learn how to code.

    Learning to code is a never ending, rewarding, frustrating, enlightening task. In this article you can see what is the generic roadmap (in my personal opinion) of a developer. As each of us is different, probably a generic roadmap won't suit your needs perfectly, if you are new to coding, I suggest you find a mentor so you can both tweak it to your case.

Frontend developer

  • New: Introduce guidelines to learn how to become a frontend developer.

    This section is the particularization of the Development learning article for a frontend developer, in particular a Vue developer.

    A Front-End Developer is someone who creates websites and web applications. It's main responsibility is to create what the user sees.

    The basic languages for Front-End Development are HTML, CSS, and JavaScript. Nowadays writing interfaces with only the basic languages makes no sense as there are other languages and frameworks that make better and quicker solutions. One of them is Vue, which is the one I learnt, so the whole document will be focused on this path, nevertheless there are others popular ones like: Bootstrap, React, jQuery or Angular.

    The difference between Front-End and Back-End is that Front-End refers to how a web page looks, while back-end refers to how it works.

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)
    

Git

  • New: Introduce git and how to learn it.

    Git is a software for tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows (thousands of parallel branches running on different systems).

Park programming

  • New: Introduce the park programming concept.

    Park programming is as you may guess, programming in parks. It includes guidelines on:

    • How to park program
    • Finding the best spots
    • Finding the best times

Javascript

Javascript snippets

  • New: Concatenate two arrays.

    const arr1 = ["Cecilie", "Lone"];
    const arr2 = ["Emil", "Tobias", "Linus"];
    const children = arr1.concat(arr2);
    

    To join more arrays you can use:

    const arr1 = ["Cecilie", "Lone"];
    const arr2 = ["Emil", "Tobias", "Linus"];
    const arr3 = ["Robin"];
    const children = arr1.concat(arr2,arr3);
    
  • New: Check if a variable is not undefined.

    if(typeof lastname !== "undefined")
    {
      alert("Hi. Variable is defined.");
    }
    
    feat(vue_snippets#Run function in background): Run function in background

    To achieve that you need to use the javascript method called setInterval(). It’s a simple function that would repeat the same task over and over again. Here’s an example:

    function myFunction() {
        setInterval(function(){ alert("Hello world"); }, 3000);
    }
    

    If you add a call to this method for any button and click on it, it will print Hello world every 3 seconds (3000 milliseconds) until you close the page.

    In Vue you could do something like:

    <script>
    export default {
      data: () => ({
        inbox_retry: undefined
      }),
      methods: {
        retryGetInbox() {
          this.inbox_retry = setInterval(() => {
            if (this.showError) {
              console.log('Retrying the fetch of the inbox')
              // Add your code here.
            } else {
              clearInterval(this.inbox_retry)
            }
          }, 30000)
        }
      },
    

    You can call this.retryGetInbox() whenever you want to start running the function periodically. Once this.showError is false, we stop running the function with clearInterval(this.inbox_retry).

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 the components property of the module:

    ```javascript export default { name: 'Inbox', components: { X } }