There are a few optional settings you can enable for the console.
1. Hide Network: Hides all network msgs, for example 404 errors (e.g. an image that cannot be found).
2. Preserve Log: Keeps previously printed msgs on the console after refreshing the page.
3. Selected Context Only: Show only msgs from your selected context (can be top, which is the current page, an iframe it page has any, a extension or a service worker).
4. Log XMLHttpRequests: Shows a msg for each AJAX call made by the page.
5. Eager Evaluation: Shows results of the Console as you type (without the need to hit enter).
6. Autocomplete from history: As you type, previously entered commands are shown.
console (in lowercase) is a special object with an API with some helpful methods.
1. console.log is the most common popular method from API and can be used to print arbitrary messages (strings and variables separated by commas).
2. console.table can print and array/list (e.g. people) of objects as a table, where each row is a single object (e.g. person), and each column an attribute of the object (name, age, etc).
Both can be used to understand the structure of the data used by the app (e.g. AJAX responses).
Here is an example that print on the console using both console.log and console.table.
Almost everything that looks like javascript data can be stored as a variable on the console, for further manipulation and inspection.
1. From the Network Panel: On AJAX responses that are displayed on the Network Panel, you can go to the Preview section, right click the request and select "Store as global variable".
2. From the Console Log: Right click any Objects or Arrays or JSON data and select "Store as global variable".
In both cases a new console message will appear displaying the name of the variable where the data was stored.
Since the data is now stored in a variable, it's no longer just a message on the console. It's a javascript object that you can manipulate it and play around with.
2. Then refresh the page. You'll see 8 AJAX calls, click on the people.json request (the url).
3. That will redirect you to its details on the Network Panel (more on that later). Click on people.json and then on the Preview tab. That will show you the entire response which you can expand to see its details.
4. Right click on (7 array of people) and select "Store as global variable". These 4 previous steps can be used to inspect AJAX results in detail.
Right now, the AJAX response should be stored on a variable named temp1. Try this on the console
temp1.filter(person => person.isActive)
That should filter the 7 people and only show those who are active. Now try this:
temp1.map(person => person.age)
That should've printed only the ages of the 7 people as a table.
Finally, try this to copy the entire content of a the variable to the clipboard:
copy(temp1)
How would you print in a table only the ages of people that are active (hint: you can do things like filter().map())?
On the console you'll see 5 functions that were called until an error stopped the JS execution. Click on each one starting from the bottom to know what happened.
What's the name of the 3rd function called?
Console: Open as a Drawer
In the previous example the back and forth between the different panels made it difficult to understand what was going on.
In those cases is better to have the other Panel (Sources in this case) selected and open the Console as a separate drawer, so both can be used at the same time.
1. Click on the first function of the stack trace, which will take you to the source file in the Sources Panel.
2. Now hit ESC to make the console show up as a drawer on top of the Sources Panel. Now when you click each part of the stack trace you won't be redirected to the other panel.
Visually, it looks like there is something wrong with the bottom component. Instead of the birth year we are getting undefined multiple times.
Let's look in the console and see what's happening.
1. The first component prints the first and last names. Then it adds the full names to each person and tries to display those.
2. But, there is an error when it tries to add the full name. Javascript stops the execution of everything after an error, unless explictly told not to do that (which isn't the case 99% of the time).
3. The bottom component never gets to the point of calculating the birth year which was the final step of the page's execution.
Who should you assign the BUG to?
Console: Querying the DOM ($ and $$)
When you load a page the browser receives the HTML string and creates the DOM (Document Object Model), an object representation of the same page that Javascript can use to manipulate the page (add content, change styles, listen to events like clicks, etc).
Using the console we can have quick access to the page's DOM and do everything a Front End Dev can with Javascript, right in the browser, without the need of setting up anything or have access to the source code.
The main two things you can do with the DOM are:
1. Query/select elements (e.g. all links aka anchor tags, or all paragraphs aka p tags).
2. Once with some elements selected you can modify them. All changes to a DOM element are immediately reflected on the actual page.
Want to change a page dynamically somehow? Use the DOM with Javascript.
What is the Elements panel of devtools? It's just a visual representation of the DOM.
Open this page. Try the following command on the console.
document.querySelector('.app')
That DOM API method selects the first tag in the page with the class "app" and prints it in the console (in this case app contains basically the whole page, which is a navigation and some content). Now try:
document.querySelectorAll('.app p')
The previous code will select all paragraphs of the app (p tags inside the div with class app). Hover through the results and you'll see the element highlighted in the page, and if you click it, you'll get redirected to it in the Elements panel.
The devtools provides some useful aliases for document.querySelector and document.querySelectorAll. They are $ and $$. $$('p') should get you the same result as the previous command.
This kind of Javascript querying can be useful to catch things that are not easily catch visually by inspecting using the Elements panel or to repeatedly inspect the same elements over and over agains after refreshing the page several times.
How many links with the class "link" are in the page?
How many links (of any kind) are in the page?
With an element selected you can do all kind of fancy stuff. Everything Javascript provides. For instance, try:
$('h1').textContent.length
$('h1').getBoundingClientRect()
$('h1').style.color = 'magenta'
The first gets you the character count of the heading.
The second gets you the exact position of the heading in relation to the viewport.
As mentioned before, in the console you have the full power of Javascript available to you. You don't need access to the Front End repository and source code to execute some advanced Javascript.
Open this page, select each form element in the Elements panel and execute the following after each selection (as shown in the video).
When doing accessibility test on a page, a common problem is to get into a focus trap. You start to navigate the page with tabs and at some point the focus is lost or on something invisible.
An useful tool for that is document.activeElement. That property on the document Javascript object always returns the currently active element. We can use that to print it in the console in case it is visually difficult to find.
Inspect this very page hit tab once and run on the console:
document.activeElement
Then right click the result on the console and select "Reveal in Elements panel" to see exactly which HTML element has the focus.
Open this page, start tabbing and set the focus on the cta that says "I'm a button". Then hit tab again.
Where is the focus? Use document.activeElement to find out.
What's the id of the invisible element that traps the focus?
Sometimes, you know there is a defect related to an specific element (e.g. a button), but don't know what's exactly causing it.
Using Monitor Events you can get log specific events or all events that happen to an element.
Type the following:
monitorEvents(document.body)
That will log in the console every single event/interaction on the whole page.
To monitor the events of an element just type monitorEvents() with the element in the between the parenthesis:
An easy way to do that is to inspect an element you want to monitor, that will save a reference to it in $0 and then type monitorEvents($0).
Open this page. Click the first button, it should be toggle the visibility of an element.
Click the second in the magenta part. Tt should do the same. Now do it in the white part with the text. It shouldn't work. Monitor that second button click events on the magent part and then in the white part. You can do that by adding 'click' as the second param of monitorEvents:
monitorEvents($0, 'click')
On the object logged in the console, look for the target value in both cases.
What tag is logged as the target in the white part?
What tag is logged as the target in the magenta part?