Search for:

Exciting Web Development Journey – The basics

Now that we have a cool development environment to brag about, why don’t we really use it? If you have no clue what I’m talking about, take a look at the series where we teach some concepts and prepare an exquisite, flexible, versatile software development environment with Docker.

My motivation

It is tough to please everyone when it comes to using the right tools, frameworks and technologies to become a good web developer, but we all concur that HTML, CSS and JavaScript are the nuts and bolts of web development. Therefore let’s get to know them and try to have fun on our journey!

HTML, CSS and Javascriptjs

I don’t want to reinvent the wheel; we all know there are many free interesting courses about this theme; there are many good CSS frameworks and JavaScript frameworks you should use or continue using. Nevertheless, during my long walk developing software, I can see many traps that people fall into due to a lack of understanding of those three guys’ basics. Still, if you stick with me, you will have a practical approach while learning a little bit of them.

What are HTML, CSS and JavaScript?

Those three are the foundational coding languages of the internet. They all work together to produce a web page. I would say that HTML adds meaning to raw content by marking it up, CSS formats that marked-up content and JavaScript is for making that content and formatting interactive, but it would sound boring, and most of the people newbie in this web development world wouldn’t still really understand or even get the big picture of it.

Therefore I always come up with the 3 friends analogy that I rescued from my childhood playing with Lego to make it clearer.

Let’s say that HTML is the first friend called The Builder responsible for the structure and content of a web page.

HTML - The builder

CSS is the second friend called The Artist, responsible for styling the web page’s content to give it a more appealing look and feel.

CSS - The artist

JavaScript is the third friend called The Wizard responsible for giving an interactive approach to the web page, allowing users to change the web page’s content and style providing such sensation that the page is alive.

JavaScript - The wizard

All of them, The Builder, The Artist and The Wizard, are essential for a web page to work seamlessly and beautifully.

For sure, I am pretty much talking about the Front-end Developer role kind of thing. We will cover some of the Backend Developer roles later, most likely in the next posts.

Let’s see how it works!

Scenario

Imagine that you are a front-end web developer. You are asked to cater to a wider variety of visitors on the Sharing Is The Key website, and you decide to incorporate support for light and dark themes keeping the brand identity. To demonstrate support for themes using CSS, you create a simple, proof-of-concept web page, and you write a JavaScript function to toggle the theme.

Learning goals

  • Develop a simple web page using HTML.
  • Style the page elements using CSS.
  • Define and create themes using CSS.
  • Add functionality for switching the theme using JavaScript.
  • Use browser developer tools to inspect the web page.

What you will need

  1. VS Code, the cross-platform code editor. Or one of your preference.
  2. Docker Desktop latest stable version. You can see how to set it up here.
  3. Familiarity with at least one programming language. You don’t need to be an expert.
  4. A computer running one of the following:
    • Windows: Windows 10 Home or Professional
    • Mac: macOS 10.9 or later
    • Linux: Ubuntu, Debian, Red Hat, Fedora, or SUSE

Project structure

Create a simple project structure that includes five files: an HTML file, a CSS file, a JavaScript file, a development container configuration file, and a Docker image file. You also add two VS Code extensions to simplify preview the web page in VSCode.


C:\SITK\WEBDEVJOURNEY\SITK-THEMES
¦   app.js
¦   index.html
¦   main.css
¦   
+---.devcontainer
        devcontainer.json
        Dockerfile

Let’s do this together!

If you prefer the CLI interface like myself, follow the Powershell or Windows Terminal section’s instructions below. If you prefer the VS Code interface, click here and follow the instructions under Create a new folder and Create some files sections.

Powershell or Windows Terminal

Getting to know Powershell or Windows Terminal if you use Windows or Shell if you use Linux is mighty, and you will need them sooner or later in your software development career. Therefore, I strongly recommend starting to use them as soon as possible. I prefer to use Windows Terminal, and from now on, I’ll call it “terminal” for short.

Open the terminal and run the following command:

New-Item -path "c:\sitk\WebDevJourney\SITK-themes\.devcontainer" -type directory

You should see something like this.

creating SITK-themes project folder structure

I created the SITK-themes project folder under the WebDevJourney folder just because this is the first of many projects in our Web Development Journey, but you can choose the folder you want.

Next, let’s create the HTML, CSS and JavaScript files under the SITK-themes folder running the command below.


New-Item -ItemType "file" -Path "c:\sitk\WebDevJourney\SITK-themes\index.html", `
                                "c:\sitk\WebDevJourney\SITK-themes\main.css", `
                                "c:\sitk\WebDevJourney\SITK-themes\app.js"

You should see something like this.

creating HTML CSS and JavaScript files under SITK-themes folder

Next, let’s create the Development Container configuration file and the Docker file that contains the Linux Alpine tiny distro.


New-Item -ItemType "file" -Path "c:\sitk\WebDevJourney\SITK-themes\.devcontainer\devcontainer.json", `
                                "c:\sitk\WebDevJourney\SITK-themes\.devcontainer\Dockerfile"
creating SITK-themes Development Container config file and Dockerfile

It is not really necessary to have this Development Container since we will not do anything complex here, but let’s get used to creating containers for all projects to keep our Software Development Environment well organized. Another remarkable advantage is that you will not need to install all software dependencies, VS Code extensions, and so on in the host to work with the project whether you format your machine later or work on it in another machine right away. If you are confused, take a look at a series of four posts where we depict this matter in more detail.

To make sure that you accomplished this task, run the following command.

Tree "C:\sitk\WebDevJourney\" /F | Select-Object -Skip 2

You should see something like this.

checking SITK-themes project tree

Now we have the SITK-themes project folder structure and files ready, let’s code!

In your terminal, make sure you are under the c:\sitk folder or in the folder you chose previously and run the following command.

cd .\WebDevJourney\SITK-themes\; code .

In your terminal, you should see something like this. Plus, it will open the VS Code in the SITK-themes project folder.

open VSCode via powershell command line

When VS Code is open, it will detect there is a Development Container configuration file devcontainer.json and will ask you to reopen the project into a Dev Container, but for now, ignore this notification because we don’t have anything in there yet.

SITK-themes project in VS Code

Press Ctrl + Shift + E to open VS Code Explorer to access the files or go to the menu View > Explorer.

Developing inside a Container

In your project, the devcontainer.json file tells VS Code how to access or create a development container with a well-defined runtime stack and tool. This container can run an application or run the required sandbox tools, libraries, or runtimes for a codebase to operate.

Workspace files are placed or copied, or cloned from the local file system into the container. Extensions are mounted and run within the container, where the tools, platform, and file system are completely accessible. This means that only by connecting to a separate container can you seamlessly switch your entire development environment. In summary, it is handy when you work on projects that require different development frameworks, libraries and platforms.

Copy the content below to the devcontainer.json file.


{
	"name": "SITK - Themes",
    "build": {
        "dockerfile": "Dockerfile",
    },
	"settings": {
		"terminal.integrated.shell.linux": "/bin/bash"
	},
	"extensions": [
		"eamodio.gitlens",
		"tht13.html-preview-vscode"
	],
}
JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition – December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

From top to bottom, this JSON file contains the name of this Dev Container,  the docker file name, which contains the instructions for Docker to build the image for the container, the settings for an integrated Linux shell in the VS Code, and the two extensions you are going to need for this project.

Copy the content below to the Dockerfile file.


FROM alpine

RUN apk --update add git less openssh && \
rm -rf /var/lib/apt/lists/* && \
rm /var/cache/apk/*

As I said previously, we will use Alpine, one of the most lightweight Linux distribution, and that is all we need for this project. Always bear in mind that the lesser we need to accomplish a task, the better.

Let’s code HTML

Now let’s call our friend The Builder to start building our web page.

All HTML documents must start with a document type declaration: <!DOCTYPE html>.

The HTML document itself begins with <html> and ends with </html>.

The visible part of the HTML document is between <body> and </body>.

VS Code provides basic support for HTML programming out of the box. Syntax highlighting, intelligent completions with IntelliSense, and customizable formatting are available.

  • Open index.html by selecting the index.html file, type html:5, then hit Enter.

HTML5 template code is added to the file.

  • Edit your code so that it looks like the following, then save the file with Control + S or go to the menu File > Save.
html5 code template

The tag document type <!DOCTYPE html> indicates this is HTML5 code. If possible, always stick with the latest HTML version. Why? Well, because it is becoming a new standard, it is faster and reduces development time. It is modern because it works along with CSS3. It lets you do things previously impossible and supports mobile devices.

While we are not going to dig deeply into the definition of all the HTML elements, we will point out a few important stuff. The meta tag, which sits inside the head tag <head> shows metadata information that would not normally be available to the user unless the source code is shown in their browser. Meta elements or tags provide detailed and important information about the webpage. For instance, they help search engines display results to people.

The UTF-8 character set (charset) may seem trivial, but it is important for deciding how computers perceive characters. If the charset is missing, it might result in a security issue. Behind Charset, there is quite a bit of history and technical knowledge.

Viewport

HTML5 introduced a method to let front-end developers take control over the viewport through the <meta> tag. The viewport is the user’s visible area of a web page. You should include the following <meta> viewport element in all your web pages:

This gives the browser instructions on how to control the page’s dimensions and to scale.

The width=device-width part sets the page’s width to follow the device’s screen-width, which will vary depending on the device.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

The initial-scale=1.0 part sets the initial zoom level when the browser first loads the page.

Head

The webpage’s title appears at the top of a browser window and is useful in a few ways. The title is used by and displayed in search engines, for instance. Let’s get a title added. Please change it to Sharing Is The Key, as shown below.

html page title

You can directly write the CSS code into the head of the web page, called internal CSS, to style the page’s HTML elements. It is best practice, however, to keep HTML structure and CSS styling apart.

It is called external CSS to have a distinct CSS file. When it is succinct and compartmentalized, the code appears to be simpler to read and understand.

You may use one or more external style sheets to serve several web pages. Instead of updating each HTML page with duplicated CSS, changes can be made once, and updates can be sent to all dependent pages.

  • In Visual Studio Code, add a blank line after the <title> element, type link and hit Enter.
  • Update the href to main.css and save the file with Control + S or go to the menu File > Save.
Link CSS to HTML

Body

  • Adding a heading <h1>, paragraph <p>and create a list item <li>.
  • Edit your code, or copy the code below and paste it between the opening <body> and closing </body> body tags.

    <h1>SITK - Themes</h1>
    <p id="tasks">Following Tasks:</p>
    <ul>
        <li class="list">Adding visual styles </li>
        <li class="list">Adding light and dark themes </li>
        <li>Switching the theme button </li>
    </ul>

An ID attribute id="tasks" used in the <p> will be used for styling this specific element as soon as we have code in the CSS file. The class attribute class="list" used in the <li> will be used for styling all elements of the same class.

Each list item <li> element is grouped into an unordered list <ul>.

Now that we have our simple web page properly structured, close VS Code and reopen it, but at this time, choose to reopen the project into the Dev Container when asked to do so.

Reopen SITK-themes project in a Dev Container

Click on Starting Dev Container (show log) as shown below.

VS Code Starting Dev Container show log

Please wait for VS Code to recognize a Dev Container configuration file, build the Alpine Linux container based on the image specified in the Dockerfile, set up the integrated Linux shell terminal, install the two VS Code extensions and be ready. The whole process takes one minute or so.

Once it is done, roll up the integrated terminal and see the HTML preview properly installed.

VS Code HTML preview extension

Now you have everything ready, resize the integrated terminal to see the whole HTML code and press Ctrl + Shift + V, which is the shortcut to the HTML preview, and here we go.

SITK-themes HTML page preview

To make it even better, grab the HTML preview and drag it to the right, as shown in the video below.

This is really handy when you want the coding to reflect immediately in the preview, as you can see below.

Sometimes things happen around us, and we don’t even notice. Please take a breath and realize that you are coding a simple HTML page into an Alpine Linux container with all you need to do so. So, congratulations on this accomplishment, but we are not done yet.

Many times you will need to troubleshooting to find some issues on the page. Let’s look at some useful developer tools in the browser where the page will actually run.

Developer tools

By opening the HTML file in a browser, you can preview your web page locally. Your browser points to the local file path instead of a website address that starts with https://. In my case, they will look like this: file:///C:/sitk/WebDevJourney/SITK-themes/index.html. If you saved the project in a different directory, don’t forget to change the path. Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.html in your preferred browser. I’ll use Google Chrome.

You should see something like this.

SITK-themes running on Google Chrome
  • Open developer tools by pressing F12.
Developer tools - Google Chrome
  • Select the Elements tab
Developer tools - Google Chrome - Element tab
  • Rollover, select the HTML elements and open the disclosure triangles and explore them all.
Developer tools - Google Chrome - Element tab - exploring elements

In Developer Tools, the Elements tab shows you the DOM as rendered by the browser. It is also important to see when debugging how the browser interprets the source code.

DOM

DOM is a cross-platform and language-independent interface that treats an XML or HTML document as a tree structure wherein each node is an object representing a part of the document. The DOM represents a document with a logical tree.

Inspecting the page in a browser provides all sorts of useful information and can help you troubleshoot problems. You can also view CSS details with the inspector, as you’ll see soon.

It is not a big deal, but here is our first web page! It seems that although it is simple, we can put a little style to make it look better. Let’s call The Artist to decorate it.

Styling HTML with CSS

You may decide how your page should look by using CSS. The fundamental principle is to target HTML code and then define what the style should be.

Let’s apply CSS styles to page elements, add CSS code to support light and dark themes, and check the developer tools’ results.

External CSS

One advantage of external CSS is that several HTML pages can be connected to the same CSS file. If you make a change to the CSS, the style will be applied to each page. Designating an HTML file for page structure, a CSS file for styling, and a JavaScript file for event or interaction is called Separation of Concerns. We already have connected the CSS to HTML by adding this code <link rel="stylesheet" href="main.css"> to the index.html previously in this post.

CSS rules

Let’s imagine that The Builder built a house, and you’ve got the keys to all doors, and you are going decorate all of them. First, pick a door, then unlock it with the proper key. Once you have access to a room, you can decorate whatever you want. You could paint the walls blue, or you could set the floor to be hardwood. You pick a room and define the rules for how it should look. You may add the same style to multiple rooms. That is what CSS does.

In VSCode, open the main.css file and type this.


body {
    font-family: monospace;
}

ul {
    font-family: helvetica;
}

It is good practice to use CSS rules to style HTML. The unordered list element ul {} is a selector, which styles the <ul> HTML element. The declaration is font-family: helvetica and says what the font style should be. The property name is font-family , and the value is helvetica.

As you can see, the whole body font should be monospace, but only the Header1 element <h1> and the Paragraph element <p> were styled with this font. We use to say that the style cascaded from the body element to the Header1 and Paragraph elements because they are the body’s children and therefore inherit from their parent, but this only happens if no other style was defined for them. On the other hand, the Helvetica font took precedence over the monospace for the unordered list <ul> because it was explicitly defined.

CSS Rules

Selectors

ID and class selectors allow you to apply styles to custom attribute names in the HTML. An ID is used to style one element, and it should be unique, whereas classes can style multiple elements.

Type or copy the following code into your CSS file after the ul selector previously added.


li {
  list-style: circle;
}

.list {
  list-style: square;
}

#tasks {
  font-family: monospace;
}

The custom attributes are called .list and #tasks. The class selector list is prefixed by a period, while the ID selector is tasks and has a hashtag sign prefix. You choose their names as long as they match what you have defined in the HTML.

Save the changes and press Ctrl+Shift+V to open the HTML preview.

CSS Selector

Notice that all list items li were styled to have a circle for the bullets, but all list items with class="list" were defined to have squared bullets.

SITK light theme

Next, let’s add support for a colour theme for the SITK-themes web page. For the light theme, let’s use hex colour codes for the font colour (#0b0b0b, Cod Gray 1) and the background (#c8b568, Laser 1).

  • In the main.css file, add the following code at the end.
.light-theme {
color: #0b0b0b;
background: #c8b568;
}
  • In the index.html file, update the <body> element with a class name, light-theme, so the class selector for the light theme will apply the styles correctly.

<body class="light-theme">

apply light-theme to SITK-themes

View applied CSS using developer tools.

  • Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.htmlin Google Chrome or Edge.
  • Open developer tools by pressing F12.
  • Select the Styles tab.
  • Select the Elements tab.
  • Rollover and select the HTML elements.
  • Select the <body> element. Notice the light-theme applied.
checking CSS applied in the developer tools
  • Open the disclosure triangles.
  • Select the <ul> element. Notice the custom style font-family: helvetica;, which overrides the style for the <body> element.
CSS overriding example

SITK dark theme

Now let’s set up plumbing for the dark theme in preparation for the last part in which we will allow theme switching on the web page.

  • Let’s add some constants to the page root in the main.css file.
:root {
--laser1: #c8b568;
--white: #ffffff;
--black: #0b0b0b;
}

The :root selector represents the <html> element in the HTML page. There are some situations where the best practice is to define a set of global CSS variables in the :root element. Here, we are defining three colour variables attached to the page root.

  • At the end of the main.css file, add the dark-theme selector and update the light-theme selector.

.light-theme {
--bg: var(--green);
--fontColor: var(--black);
}

.dark-theme {
--bg: var(--black);
--fontColor: var(--green);
}

In the code above, we defined some new variables, bg and fontColor, to specify the background colour and font colour. We used the var keyword to specify variables to use as the property values. We already set the values previously in the :root selector.

  • Next, in the main.css file, let’s add the following code after the :root selector, replacing the current body selector.
* {
color: var(--fontColor);
font-family: helvetica;
}

body {
background: var(--bg);
}

The * selector is a universal selector that applies to all page elements, except where a more specific element selector overrides it. Here, we use it to set the default color property for all page elements. For the color and background properties, you specify the variables defined in the light and dark theme selectors.

  • Remove the selector #tasks in the main.css, so that we can apply the same font to all elements.
  • To view the dark theme, manually let’s edit the default theme in the <body> element to dark-theme, and then press Ctrl+Shift+V to see HTML preview.
SITK-themes dark-theme preview
  • Let’s edit the <body> element to switch the default back to the light theme.

Javascript

JavaScript or ECMAScript is a programming language that allows you to add web page interactivity. Actually, JavaScript is the most commonly used programming language in the Software Development industry, according to Stack Overflow 2020 survey. It is nearly used by 70% of professional developers.

Stack Overflow is the largest, most trusted online community for developers to learn, share​ ​their programming ​knowledge, and build their careers for those who don’t know.

Now let’s call our friend The Wizard to give some functionality to our page!

When you click a button, JavaScript is the code that determines the event or action that will occur, such as opening a pop-up window. Using JavaScript, without reloading the web page, you can add or delete content like text. You can always use the browser to test and get feedback about your scripts as a web developer.

We will build a button to switch between light and dark themes and then wire the JavaScript code button to make the actual theme switch. When this is done, we will review our work using the developer tools.

Link HTML to JavaScript

Following the Separation of Concerns pattern recommendation, let’s use the separate JavaScript file previously created and link it to the index.html.

  • Right after the unordered list closing tag </ul> start a new line and type script:src, fill the double quotes with our JavaScript filename app.js  press Enter and save.
Link JavaScript to HTML

The script element could be placed in the <head> or elsewhere in the <body>. However, as best practice, putting <script> at the end of the <body>, allows all the page content to display on the screen first, then load the script after. This best practice will provide a better user experience when the project has huge JavaScripts to load on the page.

  • Let’s add fault tolerance so we can detect when a feature is not supported or available. After the script link you’ve just added, add a new line with the <noscript> element, which can be used to show a message if JavaScript is deactivated. Copy or type the code below and save the changes.

<noscript>You need to enable JavaScript to view the full site.</noscript>

Add JavaScript fault tolerance

Strict mode

When we start using JavaScript, our initial focus is often working with numbers, math, text manipulation, dates, and information storage. Sometimes JavaScript makes assumptions about the type of data we enter; assignment, math, or logical equality can give you unexpected results. Even if the result is an error, JavaScript tries to make the code run smoothly and provide you with a solution. To fix this behaviour, we can enable a strict mode that reduces silent errors, improves performance, provides more alerts, and reduces the number of unsafe features.

Let’s open app.js and type this code 'use strict'.

JavaScript strict mode

Toggle the theme button

We will need a button to switch themes.

  • In the index.html page, let’s add a button element <button>. Let’s put this at the end of the list inside of the <div> element. Copy or type this code below in a new line right after the unordered list closing tag </ul>.
<div>
  <button class="btn">Dark</button>
</div>
adding button to toggle the theme
  • In the main.css file, add a selector for the button. To make the button colours different from the general light or dark theme colours, set the color and background-color properties in the button selector. This selector, specific to the button, overrides the universal selector * used to apply font colours in our CSS file. Type or copy and paste the code below to the end of our CSS file.
.btn {
  color: var(--btnFontColor);
  background-color: var(--btnBg);
}
styling button to toggle theme
  • Next, let’s add some rules for the size, shape, appearance, and button absolute position. The following CSS creates a round button to the right of the page heading. Type or copy and paste the code below, replacing the existing button selector.
.btn {
  position: absolute;
  top: 20px;
  left: 250px;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  border: none;
  color: var(--btnFontColor);
  background-color: var(--btnBg);
}
styling button to toggle theme
  • To improve the button’s appearance, let’s add a pseudo-class selector btn:focus after the button selector. By setting the outline-style rule to none, you eliminate a rectangular outline when the button is selected or receives focus. Type or copy and paste the code below to the end of our CSS file.
.btn:focus { 
    outline-style: none;
}
eliminating button outline when clicked or focused
  • Next, let’s update the CSS for the light and dark themes. Let’s define some new variables, btnBg and btnFontColor, to specify the button-specific background colour and font colour. Update the light-theme and dark-theme selectors with the code below.
.light-theme {
  --bg: var(--laser1);
  --fontColor: var(--black);
  --btnBg: var(--black);
  --btnFontColor: var(--white);
}

.dark-theme {
  --bg: var(--black);
  --fontColor: var(--laser1);
  --btnBg: var(--white);
  --btnFontColor: var(--black);
}
updating ligh-theme and dark-theme selectors

Event Handler

You need an event handler in your JavaScript file to make the button do something when you click it. Therefore we need to listen to the button click event. But, before you add the event handler, you will need a reference to this button.

  • In the app.js file, use document.querySelector to get the button reference. The document is a global variable representing the actual web page, and the querySelector method returns the first element that matches a specified CSS selector in the page.

const switcher = document.querySelector('.btn');

  • Let’s add the event listener and the event handler for the click event. In the following code, we are adding a listener for the click event. The function passed into the event listener is the actual event handler.
switcher.addEventListener('click', function() {
    document.body.classList.toggle('dark-theme');
});

We used the toggle method in the previous code to move the element to the dark-theme class. This will immediately add the dark theme styles instead of the light theme. To view the correct theme, however, the button label also needs to be changed, so you need to add a condition to verify the current theme and update the button label. Please add this command inside the event listener, right after the toggle command.

  let className = document.body.className;
  this.textContent = className == "light-theme" ? "Dark" : "Light";

In the code above, we created a variable className and assigned the body element class name to it, and we assigned a ternary operator result to this.textContent. The this is the switcher variable that points to the button element. In summary, this is the button. The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (?), then an expression to execute if the condition is truthy followed by a colon (:), and finally the expression to execute if the condition is false. This operator is frequently used as a shortcut for the if statement.

Press Ctrl+Shit+V to reload the HTML preview page.

adding JavaScript to the SITK-themes project

Now you can click on the button to contemplate our friend The Wizard‘s job done!! Congratulations, we made it; we built our first beautiful web page and gave it life.

Console message

Sometimes to better understand the page behaviour running on the browser, we can use console messages. It is a hidden message that will not appear on the web page but will show up in the browser developer tools.

In app.js, add a call to console.log after the ternary operator statement, but still inside the event listener.

  console.log('current class name: ' + className);
console logging in SITK-themes project

Check console messages in the browser.

  • Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.htmlin Google Chrome or Edge.
  • Open developer tools by pressing F12.
  • Select the Styles tab.
  • Select the Elements tab.
SIT-themes project light-theme selected
  • Select the <body> element. In the Styles tab, look at the applied theme. If the current theme is dark, the dark-theme styles are applied.

Make sure the dark theme is selected.

SITK-themes project dark-theme selected
  • Select the Console tab to see the console.log message, “current <body> class name: light-theme dark-theme”.
SIT-themes project light-theme selected - check console log

Using the console log, we can better understand how the CSS theme switching is handled. Both class names are applied to the <body> element when we switch to the dark theme. However, the last class name applied, the dark theme, takes precedence. In the Styles tab, you can see that the dark theme rules override the light theme rules, shown using strikethrough text.

SIT-themes project light-theme selected - check console log details
  • To see the viewport metadata behaviour explained previously, which is very important to build a responsive web page that also fits mobile devices, click on the Toggle device toolbar button and open <head> HTML element.
SITK-themes project light-theme selected - mobile
  • Toggle to the dark theme.
SITK-themes project dark-theme selected -mobile
  • To understand the importance of the viewport metadata, comment the line 6 in index.html. Go to line 6 and press Ctrl+;  and save.
comment viewport metadata in SITK-themes project
  • Reload the page by pressing F5 to apply the browser’s changes and click on the Toggle device toolbar button to change to Desktop device and toggle back to mobile.
checking the results of commenting viewport metadata in SITK-themes project
  • Now, it’s time to save our work. Uncomment line 6 in index.html by pressing Ctrl+; again and save it.
  • Commit everything with the git extension we installed in our Docker Dev Container in the beginning. This way, you will have control of the source code and track all changes from now on. Go to Source Control extension by pressing Ctrl+Shift+G.
  • Click on the Initialize Repository button to create a new git repository for source control.
  • Type the message “Adding files” to the field and click on the commit button, as shown below.
git commit changes SITK-themes

It is always a good practice to commit all changes you make to your project frequently.

If you don’t know what Git is, take a look here and find out. The SITK-themes source code can be found on our GitHub account.

Congratulations!! We’ve got the basics of front-end web development. Certainly, there is much more to learn about HTML, CSS and JavaScript, and there are some free and excellent references for this: w3schools.com and MDN Web Docs.

If you need any help or something is going wrong, let me know. It will be my pleasure to help you. If you want to extend some point, we have discussed, tell me so we can cover in the next posts.

We also have pro bono projects just in case you are interested in learning more about them.

Be aware of why we started this project by clicking here.

Learn more about other posts here.

Contact us for any suggestions. And follow us on FacebookInstagram and Twitter.

If you are a good reader like myself, I recommend the following readings:

  • Docker Quick Start Guide: Learn Docker like a boss, and finally own your applications
  • Docker for Developers: Develop and run your application with Docker containers using DevOps tools for continuous delivery
  • Responsive Web Design with HTML5 and CSS: Develop future-proof responsive websites using the latest HTML5 and CSS techniques, 3rd Edition
  • JavaScript: The Definitive Guide: Master the World’s Most-Used Programming Language 7th Edition

See you in the next post!

xUnit, TestCafe, Docker and Jenkins - Sharing is the key

Software Testing Quality Assurance using xUnit, TestCafe along with Docker and Jenkins: an automated approach 2/3

This is the second of three posts about QA Testing using xUnit, TestCafe, Docker and let’s add Jenkins to give it an automated approach. For those who missed the previous post, it’s worth seeing it since most of the steps we are going to do here have some pre-requisites we covered there.

What is, what is used for and why Jenkins?

Jenkins logo

Jenkins is an open-source automation platform with lots of plugins designed for Continuous Integration or Continuous Delivery (CI/CD) purposes written in Java. Jenkins is used to constantly create and test software projects, making it easier for developers to incorporate project modifications and making it easier for users to acquire a new build. It also enables you to continuously deliver your applications by integrating with a wide range of testing and deployment technologies.

Continuous Integration / Continuous Delivery

Continuous Integration or Continuous Delivery is a software development practice in which developers are expected to commit changes many times a day or more regularly to the source code in a shared repository. Each commit made in the repository is then compiled. This helps the teams to identify the issues early. Besides this, many other roles depending on the CI/CD tool, such as deploying the build application on the test server, delivering the build and test results to the affected teams.

Besides all of that technical definition, Jenkins is this distinct gentleman in the image that came to serve you and make your life as a developer better. Let’s not take it for granted and make the most of Jenkins.

jenkins plugins

We all know that CI/CD is one of DevOps’ most important parts used to integrate various DevOps stages. For those who have no clue about what DevOps means, it is a set of practices integrating the development of software and IT activities. It aims to shorten the life cycle of system creation and provide high software quality for continuous integration and delivery.

With Jenkins, through automation, not only individual developers but also companies can accelerate software development. Jenkins incorporates all sorts of life-cycle development processes, including documenting, building, testing, packaging, staging, deployment, static analysis, and even more.

Jenkins’ benefits include:

  • With great community support, it is an open-source application.
  • It is straightforward to install using Jenkins docker’s official image.
  • To simplify your job, it has 1000+ plugins. You should code it and share it with the group if a plugin doesn’t exist.
  • It is cost-free.
  • It is Java-built and is, therefore, portable to all major platforms.

CI/CD with Jenkins depicted

Imagine a situation where the application’s full source code has been built and then deployed for testing on the test server. It sounds like the ideal way to build software, but there are several pitfalls in this process. I’m going to try to clarify them:

  • For the test results, developers have to wait until the full software is developed.
  • There is a strong probability that several bugs will be found in the test results. It is difficult for developers to find these bugs since they have to review the entire source code.
  • It delays the delivery process of applications.
  • There is a lack of continuous feedback on coding or architectural problems, build failures, test status and file release uploads, due to which software quality will decline.
  • The method as a whole is manual, raising the likelihood of frequent failure.

From the above-mentioned issues, it is evident that the software delivery process is sluggish, and software quality will likely deteriorate with time. This leads to disappointment with customers. So there is a desperate need for a system to exist to solve such frustration where developers would constantly activate a build and test for any change made in the source code. This is what CI/CD it’s all about. Jenkins is one of the most mature CI/CD platforms available, so let us see how Jenkins conquered the deficiencies in a simplified and self-explanatory workflow diagram below as an example.

simplified CI diagram with Jenkins

As you can see, Jenkins uses the pipeline concept to unleash the power of multiple steps according to parameters you set to perform both basic and complex tasks. When built, pipelines can build code and coordinate the work needed to push applications from commit to delivery.

Let’s make things happen now!

A useful hint I am going to give you is to use docker-compose as much as you can. Docker-compose is a tool for describing Docker multi-container applications and running them. With docker-compose, you use a YAML file to configure services for your application. Then, you build and start all the services from your configuration with a single command. Besides all of that, the YAML file is easy to read, and you will treat it as a source code and track all changes with your preferred SCM tool. Docker-compose is installed as part of the Docker Desktop. If you haven’t installed Docker Desktop yet, go to our first post of a series of four and follow the instructions.

docker-compose

Since I am using Windows, go to Powershell or Windows Terminal and create jenkins directory by running New-Item -Type Directory -Path jenkins command, as shown below.

Jenkins folder

From inside Jenkins directory type code . and hit Enter to open an instance of VSCode.

open vscode from iside jenkins folder

Create a file called docker-compose.yaml inside Jenkins folder.

docker-compose yaml file

Copy this code below into docker-compose.yaml file and save it.

version: '3.8'
services:
  cicd: 
    image: sitk/jenkins:lts
    container_name: sitk_jenkins
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - jenkins-home-volume:/var/jenkins_home
volumes:
    jenkins-home-volume:
      driver: local
      driver_opts:
        type: none
        device: c:\sitk\jenkins\jenkins_home
        o: bind

It should look like this.

docker-compose yaml file filled up

YAML is a format for human-readable data serialization that can be used for all programming languages in combination and is also used to write configuration files. It is imperative to keep this file valid, which means that we need to follow some rules and indentations. Therefore I recommend using this popular VSCode extension with more than 4.6MM installs so it can help us to validate the file.

YAML Red Hat VSCode extension

We will use the official Jenkins Docker image jenkins/jenkins:lts and extend it installing .NET Core SDK since we will restore, clean, build and unit test the eShopOnWeb solution.

Docker Jenkins

Building a new Jenkins Docker image

Let’s build the sitk/jenkins:latest image. Create the image folder inside the Jenkins folder, and create a Dockerfile file inside the image folder with the content shown below.

FROM jenkins/jenkins:lts
 # Switching to root user to install .NET Core SDK
USER root

# Show the distro information during compilation!
RUN uname -a && cat /etc/*release

# Based on instructions at https://docs.microsoft.com/en-us/dotnet/core/install/linux-debian#debian-9-
# Installing with APT can be done with a few commands. Before you install .NET SDK, run the following commands 
# to add the Microsoft package signing key to your list of trusted keys and add the package repository.
RUN wget -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg && \
    mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/ && \
    wget https://packages.microsoft.com/config/debian/9/prod.list && \
    mv prod.list /etc/apt/sources.list.d/microsoft-prod.list && \
    chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg && \
    chown root:root /etc/apt/sources.list.d/microsoft-prod.list


# Install the .Net Core SDK, set the path, and show the version of core installed.
RUN apt-get update && \
    apt-get install apt-transport-https && \
    apt-get update && \
    apt-get install -y dotnet-sdk-3.1 && \
    export PATH=$PATH:$HOME/dotnet && \
    dotnet --version

# Switching back to the jenkins user.
USER jenkins

In the end, it should look like this.

sitk Jenkins Dockerfile

Now we will build the sitk/jenkins:latest with .NET Core SDK. Create a build.sh file into the image folder with this command: docker build -t sitk/jenkins . . It should look like this.

sitk Jenkins image build shell script

Go to Windows Terminal, open a Linux terminal. In my case, I have Ubuntu 20.04 running as Windows Subsystem Linux version 2. Go to /mnt/c/sitk/jenkins/image directory and run ./build.sh . If you missed it and want to catch up, go to our first post of a series of four.

After compiling the image, you should see something like this.

sitk jenkins image compilation

Now we are ready to run docker-compose. Go back to the Windows Terminal and type docker-compose up -d and hit Enter. I recommend saving the command in a start.ps1 file, so you don’t need to remember the syntax next time.

cicd service up and running

This command will start a container in detached -d mode with the service cicd which is based on the sitk/jenkins:lts image,…

docker-compose image

…it will name the container sitk_jenkins,…

docker-compose container name

…it will map the container inside ports 8080 and 50000, which are sitting at the right side of the colon, with the same ports at the host, which are sitting at the left side of the colon. Just for curiosity, port 50000 is used in robust environments when you need to attach some Jenkins Slave Agents to run pipelines in parallel. Mapping port 8080 to host is important so we can access the service via http://localhost:8080

docker-compose ports

…and the volumes declaration maps the /var/jenkins_home directory where all Jenkins data resides inside the container, to the c:\sitk\jenkins\jenkins_home in the host. This mapping is essential to manage it and attach it to another container for upgrades purposes, backup Jenkins data. Most importantly, it will also survive the container stop/restart/deletion, which means no Jenkins data loss.

docker-compose volumes

Go back to Windows Terminal, type docker ps -f "name=sitk_" and hit Enter. If everything went right, you would see Jenkins container running.

show Jenkins container running

We are almost there, now go to http://localhost:8080, you will see something like this.

Unlock Jenkins

Follow the instructions on the screen. Remember when we mapped the container /var/jenkins_home directory with the host directory c:\sitk\jenkins\jenkins_home in the YAML file? That’s another useful applicability of docker bind volumes. You don’t need to go inside the container to access files. Therefore, open c:\sitk\jenkins\jenkins_home\secret\initialAdminPassword file, copy the password and paste it to the administrator password field and click continue.

Click on the Install suggested plugins button.

Jenkins Install suggested plugins

And wait a couple of minutes for Jenkins to download and install all plugins.

Installing jenkins plugins.jpg

After the installation of the plugins, they will prompt you to create the First Admin User.

Jenkins first admin user

Type the information required and hit Save and Continue.

fulfill all required info for the Jenkins first admin user

Let the Jenkins URL unchanged (http://localhost:8080/) and hit Save and Continue.

Jenkins instance configuration

Now we are done with Jenkins’s initial setup.

Jenkins is ready

Click on Start using Jenkins button, and there you go!

Jekins login

Before we start creating pipelines for the suggested Jenkins Workflow graph, let me share with you an important hint. Create a Powershell script to stop and remove the Jenkins container with docker-compose rm --stop --force command, name it as stop.ps1, and save it in the same directory you saved the start.ps1 PowerShell script previously. Yes, you heard it right, the command will stop and remove the container and don’t be afraid of doing so because all we need for Jenkins to work next time we start it is in the c:\sitk\jenkins\jenkins_home directory, remember?

So, let’s do this. Go to Windows Terminal under c:\sitk\jenkins directory, type .\stop.ps1 to stop Jenkins’s container.

stop jenkins container

Let’s start it over again with the start Powershell script you previously created.

starting jenkins container

Let’s make sure that Jenkins is up and running because we will need it soon. Visit http://localhost:8080 and enter the admin user credentials you previously created and sign in.

Jekins login

Since we will check out from GitHub restore, clean, build and pack it, we will need .NET SDK Support plugin for Jenkins. Go to Manage Jenkins left panel option, click on Manage Plugins.

MAnage Jenkins manage plugins

Click on the Available tab, and in the search field, type “dotnet” and select  .NET SDK Support and click on the Install Without Restart button.

install NET SDK Support plugin

Please wait until it is completely installed.

NET SDK Support installed

Now we are ready to create the pipeline with some of the stages described in the Jenkins Workflow graph. Let’s use the eShopOnWeb, an ASP .Net Core application we used on posts three and four of our series of four posts. It is worth looking at them, but you can always visit our eShopOnWeb Github repository for more details.

On Jenkins’s home page, select New Item.

Jenkins New Item

Enter eShopOnWeb as the item name, select Pipeline and click OK.

enter intem name select pipeline and click ok

We suggest you give it a brief description and click on the Pipeline tab.

basic cicd pipeline for eShopOnWeb solution

Select the Pipeline script from SCM option from the Definition field.

select pipeline script from SCM

Select the Git option from the SCM field.

select git from SCM field

Copy eShopOnWeb git URL https://github.com/sitknewnormal/eShopOnWeb.git to the Repository URL field, and make sure the Script Path field is “Jenkinsfile,” and click on the Save button.

Copy eShopOnWeb git URL to the Repository URL field

Now we have to prepare Jenkinsfile because it will contain all stages that Jenkins will run in the pipeline. Therefore, go to the eShopOnWeb root folder, create the Jenkinsfile and copy the content below.

pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git url: 'https://github.com/sitknewnormal/eShopOnWeb.git', branch: 'master'
            }
        }
        stage('Restore') {
            steps {
                sh "dotnet restore eShopOnWeb.sln"
            }
        }
        stage('Clean') {
            steps {
                sh "dotnet clean eShopOnWeb.sln"
            }
        }
        stage('Build') {
            steps {
                sh "dotnet build --configuration Release eShopOnWeb.sln"
            }
        }
        stage('Functional, integration and unit tests (xUnit)') {
            steps {
                sh "dotnet test eShopOnWeb.sln"
            }
        }
    }
}

It should look like this.

Jenkinsfile eShopOnWeb

Don’t forget to rename the eShopOnWeb git URL if you forked or git cloned the project. You most probably have to change in this URL “https://github.com/sitknewnormal/eShopOnWeb.git” only the sitknewnornal highlighted in red to your GitHub username. And most importantly, don’t forget to commit and push it to your repository because Jenkins will poll it from there when the pipeline runs.

To do so, I am using the popular GitLens VSCode extension, which I recommend.

GitLens VSCode extension

Select GitLens extension and stage Jenkinsfile file by clicking the plus (+) button.

Select GitLens extension and stage Jenkins file by clicking plus button

Type a commit description “first Jenkinsfile commit” and commit the changes by clicking on the checkmark button.

commit Jenkinsfile changes

Push all changes to the eShopOnWeb GitHub repository. Hit Ctrl+Ship+P to open Command Pallet, type “Push” and “Git: Push to…” option and select eShopOnWeb remote repository on the list. If you don’t have it click on “Add a new remote…”  and follow the instructions.

git push to eShopOnWeb GitHub repository

Now that we have everything set up, let’s run the Jenkins pipeline eShopOnWeb we’ve just created.

Go back to Jenkins in the pipeline eShopOnWeb and click on the Build Now button.

click build now button

You will wait a couple of minutes for the pipeline to execute, and you will see something like this.

pipeline eShopOnWeb result

As you can see, all stages in this pipeline have succeeded! The Jenkins project source code is on our GitHub account.

Congratulations, we’ve reached a relevant part of our goal. We now have one of the most powerful and popular CI/CD tools called Jenkins, taking care of our Software Development life cycle’s important steps.

We saved the end to end test with TestCafe and more for the next post because we don’t want to make this one very long. So let’s make a series of three instead of two as we planned before.

We also have pro bono projects just in case you are interested in learning more about them.

Be aware of why we started this project by clicking here.

Learn more about other posts here.

Contact us for any suggestions. And follow us on FacebookInstagram and Twitter.

If you are a good reader like myself, I recommend the following readings:

  • Docker Quick Start Guide: Learn Docker like a boss, and finally own your applications
  • Docker for Developers: Develop and run your application with Docker containers using DevOps tools for continuous delivery
  • C# and .NET Core Test-Driven Development: Dive into TDD to create flexible, maintainable, and production-ready .NET Core applications, Kindle Edition
C# and .NET Core Test-Driven Development: Dive into TDD to create flexible, maintainable, and production-ready .NET Core applications, Kindle Edition
  • Modern Web Testing with TestCafe: Get to grips with end-to-end web testing with TestCafe and JavaScript 1st Edition, Kindle Edition
Modern Web Testing with TestCafe: Get to grips with end-to-end web testing with TestCafe and JavaScript 1st Edition, Kindle Edition
  • Continuous Delivery with Docker and Jenkins: Create secure applications by building complete CI/CD pipelines, 2nd Edition, Kindle Edition

See you in the next post!

%d bloggers like this: