Skip to content

A Node.js CLI application that will take in information about employees on a software engineering team, then generates an HTML webpage that displays summaries for each person, following Agile methodology, OO paradigm and TDD/BDD development in JavaScript.

License

Notifications You must be signed in to change notification settings

technoveltyco/bootcamp-week12-challenge

Repository files navigation

Test-Driven Development: Team Profile Generator

A Node.js CLI application that will take in information about employees on a software engineering team, then generates an HTML webpage that displays summaries for each person, following Agile methodology and TDD development process.

Table of contents

Overview

In this Challenge, you'll create an application that generates HTML files using input from a command-line interface.

The challenge

Your task is to take the given starter code and convert it into a working Node.js command-line application. This application will take in information about employees on a software engineering team, then generate an HTML webpage that displays summaries for each person. You have been provided with tests, so make sure every part of your code passes each provided test.

Getting Started

Your application should use JestLinks to an external site. for running unit tests and InquirerLinks to an external site. for collecting input from the user. The application will be invoked by using the following command:

node index.mjs

👆 Please note the index.mjs extension above. This is because the project has been developed using ES6 modules and no CommonJS syntax.

Walkthough & Screenshots

Walkthrough GIF of Team Profile Generator

Click on each screenshot to take you to the Walkthrough video, a Team Profile's live example, and an example in PDF version.

Walkthrough Video https://user-images.githubusercontent.com/2573750/222523833-77af7fda-d324-4848-b360-2ecda53db25e.mp4

Example of a generated Team Profile webpage on large screens

Example of a generated Team Profile webpage on small screens

Example of a printer-friendly version of the Team Profile webpage

Example of all running tests passed

Links

My process

I started designing the structure of the program by creating a Flowchart Diagram, Class Diagram and Sequence Diagram, so I could have a reference of the logic structure, modules and overall idea of the automated tests coverage required. Finally, I went through the ideas and doing investigation for the UX/UI Design, starting from the terminal theming, and following with the webpage design creating a visualisation on screens and a printer-friendly version.

Built with

Flowchart Diagram (Simplified)

---
title: Team Profile Generator
---
flowchart TB
    A((start)) --> B[Create new Team]
    B --> C[/Prompt Team Manager/]
    C --> D{Input data \nvalidates?}
    D -->|No| C[/Prompt Team Manager/]
    D -->|Yes| E[Add new Employee to Team]
    E --> F[/Prompt Main Menu/]
    F --> G{Add an Engineer?} & H{Add an Intern?} & I{Finish the Team?}
    G -->|No| F
    G -->|Yes| J[/Prompt Engineer/]
    J --> D
    H -->|No| F
    H -->|Yes| K[/Prompt Intern/]
    K --> D
    I -->|No| F
    I -->|Yes| L[Create HTML]
    L --> M((Finish))
Loading

Class Diagram

---
title: Team Profile Generator
---
classDiagram
    AppSingleton <.. ClientConsole
    AppSingleton "1" <-- "1" EmployeeFactory : contains
    AppSingleton "1" <-- "1" TeamComposite : contains
    Team <|-- TeamComposite
    Team "0..*" <--* "1" TeamComposite
    Employee <|-- Team
    Employee "0..*" <--* "1" Team
    Employee <|-- Manager
    Employee <|-- Engineer
    Employee <|-- Intern

    class AppSingleton {
        -TeamComposite teamsInstance
        -AppSIngleton():void
        +getInstance()$:AppSingleton

    }
    class EmployeeFactory {
        +createEmployee(String type, Object params)*:Employee
    }
    class TeamComposite {
        -EmployeeFactory factory
        -List~Team~ teams
        +getTeams():List~Team~
        +getTeam(Integer index):Team
        +addTeam(Team team):void
        +removeTeam():Team
        +clearTeams():void
    }
    class Team {
        -List~Employee~ employees
        +getEmployees():List~Employee~
        +getEmployee(Integer id):Employee
        +addEmployee(Employee employee):void
        +removeEmployee(Integer id):Employee
        +clearEmployees():void
    }
    class Employee {
        <<abstract>>
        -String name
        -Integer id
        -String email
        +createEmployee(Object params):Employee
        +getName():String
        +getId():Integer
        +getEmail():String
        +getRole()*:String
    }
    class Manager {
        -Integer officeNumber
        +createEmployee(Object params):Employee
        +getOfficeNumber:Integer
        +getRole():String ~~override~~
    }
    class Engineer {
        -String github
        +createEmployee(Object params):Employee
        +getGithub():String
        +getRole():String ~~override~~
    }
    class Intern {
        -String school
        +createEmployee(Object params):Employee
        +getSchool():String
        +getRole():String ~~override~~
    }
Loading

I extended the original models to include a more scalable architecture using the following design patterns:

  • Singleton: the App class implements this pattern to restrict the creation of more than one instance in our application. This is the main entry point in the application flow, and handles more of the errors and recovery states of the program flow.
  • Factory: due to JavaScript limitations for creating abstract classes and interfaces, the implementation of classical OO factory patterns are usually achieved by using functional patterns. However, a mixed implementation between the Abstract factory pattern and Factory method pattern was used to achieve flexibility in the design and allow the creation of model classes using 3 different approaches:
  ///
  // Examples of different ways to initialise employees/manager/engineer/intern.
  // ------------------------------------------------------------------------------
  // - With constructor:
  // const employee = new Employee(...data);
  // - With factory method:
  // const employee = Employee.createEmployee(...data);
  // - With factory abstract class method: (the one used here)
  // const employee = EmployeeFactory.createEmployee("manager", ...data);
  • Composite: used for the container classes that store multiple instances of the model object, and allowing to create and control higher level data structures like: team of employees, and list of teams. By adding these structures, it also required to extend the test suite to check the correct integration of the data structures and ensure that the desired access restrictions to the data would be accomplished.

Sequence Diagram

sequenceDiagram
    autonumber
    activate User
    User->>App:Start
    activate App
    App->>Inquirer:prompt Team Manager
    activate Inquirer
    loop Name, ID, email, office
        Inquirer-->>User:request manager data
        User->>Inquirer:input
        Inquirer->>Inquirer:Validate input
        Inquirer-->>User:output result
    end
    Inquirer-->>App:Name, ID, email, office
    deactivate Inquirer
    App->>Team:create
    activate Team
    Team-->>App:<<Team>>
    App->>Manager:Name,ID,email,office
    activate Manager
    Manager-->>App:<<Manager>>
    deactivate Manager
    App->>Team:add <<Employee>>
    deactivate Team
    App->>Inquirer:prompt Main Menu
    activate Inquirer
    loop is not stop prompt
        Inquirer-->>User:request employee data
        User->>Inquirer:chosen option
        alt option is Add an engineer
            loop name,ID,email,github
                Inquirer-->>User:request employee data
                User->>Inquirer:input
                Inquirer->>Inquirer:Validate input
                Inquirer-->>User:output result
                Inquirer-->>App:Name,ID,email,github
                App->>Engineer:Name,ID,email,github
                activate Engineer
                Engineer-->App:<<Engineer>>
                deactivate Engineer
            end
            App->>Inquirer:prompt Main Menu
        else alt option is Add an Intern
            loop name,ID,email,school
                Inquirer-->>User:request employee data
                User->>Inquirer:input
                Inquirer->>Inquirer:Validate input
                Inquirer-->>User:output result
                Inquirer-->>App:Name,ID,email,school
                App->>Intern:Name,ID,email,school
                activate Intern
                Intern-->>App:<<Intern>>
                deactivate Intern
            end
            App->>Team:add employee <<Intern>>
            App->>Inquirer:prompt Main Menu
        else option is Finish building the team
            Inquirer-->>App: stop prompt
            deactivate Inquirer
        end
    end
    App->>HTML Generator:generate
    HTML Generator-->>App:<<DOM>>
    App-->>User:<<HTML>>
    deactivate App
    deactivate User
Loading

UX/UI Design

A definition of colors and formatting of the output were created in a specific CLI module providing different utilities and helper functions.

Terminal Theming

Emoji Text Color Background Color Text decoration Behaviour Terminal UI
✔️ #008000 #000000 -- Success --
✔️ #000000 #00ffff -- Done --
⚠️ #ffa500 #000000 -- Warning --
-- #ffa500 #000000 -- Fail validate --
⚠️ #000000 #00ffff -- Info Bottom Bar
#ff0000 #000000 -- Fatal Error Bottom Bar
📂 #ffffff #000000 -- Created --
🙏 #ffffff #000000 -- Thanks --
-- #ffffff #000000 Bold Label --
-- #000000 #00ffff -- Highlight --
#000000 #00ffff -- Notify Bottom Bar
📛 #ffffff #000000 Bold Name Input Label --
🆔 #ffffff #000000 Bold ID Input Label --
📧 #ffffff #000000 Bold Email Input Label --
🏢 #ffffff #000000 Bold Office Number Input Label --
💻 #ffffff #000000 Bold GitHub Account Input Label --
🏫 #ffffff #000000 Bold School Input Label --
-- #ffffff #000000 -- Default text --
Terminal Text Art Intro

This cover intro was created but still not implemented in v1.0.

 ███████████                                       ███████████                        ██████   ███  ████                █████████                                                    █████                      
░█░░░███░░░█                                      ░░███░░░░░███                      ███░░███ ░░░  ░░███               ███░░░░░███                                                  ░░███                       
░   ░███  ░   ██████   ██████   █████████████      ░███    ░███ ████████   ██████   ░███ ░░░  ████  ░███   ██████     ███     ░░░   ██████  ████████    ██████  ████████   ██████   ███████    ██████  ████████ 
    ░███     ███░░███ ░░░░░███ ░░███░░███░░███     ░██████████ ░░███░░███ ███░░███ ███████   ░░███  ░███  ███░░███   ░███          ███░░███░░███░░███  ███░░███░░███░░███ ░░░░░███ ░░░███░    ███░░███░░███░░███
    ░███    ░███████   ███████  ░███ ░███ ░███     ░███░░░░░░   ░███ ░░░ ░███ ░███░░░███░     ░███  ░███ ░███████    ░███    █████░███████  ░███ ░███ ░███████  ░███ ░░░   ███████   ░███    ░███ ░███ ░███ ░░░ 
    ░███    ░███░░░   ███░░███  ░███ ░███ ░███     ░███         ░███     ░███ ░███  ░███      ░███  ░███ ░███░░░     ░░███  ░░███ ░███░░░   ░███ ░███ ░███░░░   ░███      ███░░███   ░███ ███░███ ░███ ░███     
    █████   ░░██████ ░░████████ █████░███ █████    █████        █████    ░░██████   █████     █████ █████░░██████     ░░█████████ ░░██████  ████ █████░░██████  █████    ░░████████  ░░█████ ░░██████  █████    
   ░░░░░     ░░░░░░   ░░░░░░░░ ░░░░░ ░░░ ░░░░░    ░░░░░        ░░░░░      ░░░░░░   ░░░░░     ░░░░░ ░░░░░  ░░░░░░       ░░░░░░░░░   ░░░░░░  ░░░░ ░░░░░  ░░░░░░  ░░░░░      ░░░░░░░░    ░░░░░   ░░░░░░  ░░░░░     
                                                                                                                                                                                                                
                                                                                                                                                                                                                
                                                                                                                                                                                                                
              ,  ,                                                           █████                
             / \/ \,'| _                                                    ░░███                
            ,'    '  ,' |,|                                                  ░███████  █████ ████
           ,'           ' |,'|                                               ░███░░███░░███ ░███ 
          ,'                 ;'| _                                           ░███ ░███ ░███ ░███ 
         ,'                    '' |                                          ░███ ░███ ░███ ░███ 
        ,'                        ;-,                                        ████████  ░░███████ 
       (___                        /                                        ░░░░░░░░    ░░░░░███ 
     ,'    `.  ___               ,'                                                     ███ ░███ 
    :       ,`'   `-.           /                                                      ░░██████  
    |-._ o /         \         /                                                        ░░░░░░   
   (    `-(           )       /
  ,'`.     \      o  /      ,'
 /    `     `.     ,'      /
(             `"""'       /              ███████████                   █████                                               ████   █████               
 `._                     /              ░█░░░███░░░█                  ░░███                                               ░░███  ░░███                
    `--.______        '"`.              ░   ░███  ░   ██████   ██████  ░███████   ████████    ██████  █████ █████  ██████  ░███  ███████   █████ ████ 
       \__,__,`---._   '`;                  ░███     ███░░███ ███░░███ ░███░░███ ░░███░░███  ███░░███░░███ ░░███  ███░░███ ░███ ░░░███░   ░░███ ░███  
            ))`-^--')`,-'                   ░███    ░███████ ░███ ░░░  ░███ ░███  ░███ ░███ ░███ ░███ ░███  ░███ ░███████  ░███   ░███     ░███ ░███  
          ,',_____,'  |                     ░███    ░███░░░  ░███  ███ ░███ ░███  ░███ ░███ ░███ ░███ ░░███ ███  ░███░░░   ░███   ░███ ███ ░███ ░███  
          \_          `).                   █████   ░░██████ ░░██████  ████ █████ ████ █████░░██████   ░░█████   ░░██████  █████  ░░█████  ░░███████  
            `.      _,'  `                 ░░░░░     ░░░░░░   ░░░░░░  ░░░░ ░░░░░ ░░░░ ░░░░░  ░░░░░░     ░░░░░     ░░░░░░  ░░░░░    ░░░░░    ░░░░░███  
            /`-._,-'      \                                                                                                                 ███ ░███                                                                                                                                                                                                                 
                                                                                                                                            ░░██████                                                                                                                                                                                         
                                                                                                                                             ░░░░░░                                                                                                                                                                             

Team Profile Page

The theming was inpired in the idea of practising UI design shapes using CSS effects and vectorised images in SVG format. In addition for usability considerations, a printer-friendly theme was created too.

To look at the sample of a generated Team Profile follow the links below:

Test Coverage

Tests were created for all the models implemented in the diagram of classes, covering ~100% of the code.

You can run the tests from the project root folder using npm run test.

What I learned

Use this section to recap over some of your major learnings while working through this project. Writing these out and providing code samples of areas you want to highlight is a great way to reinforce your own knowledge.

To see how you can add code snippets, see below:

<h1>Some HTML code I'm proud of</h1>
.proud-of-this-css {
  color: papayawhip;
}
const proudOfThisFunc = () => {
  console.log("🎉");
};

Continued development

The following tickets has been created for future development:

  • Bug fixes & Improvements
  • Functional tests for the document generation.
  • Remote Terminal & Security implications
  • Landing page
  • Docs page

Useful resources

Author

Daniel Rodriguez

Acknowledgments

The teacher and TAs that help us with resources and support to my questions during the development of this project.

About

A Node.js CLI application that will take in information about employees on a software engineering team, then generates an HTML webpage that displays summaries for each person, following Agile methodology, OO paradigm and TDD/BDD development in JavaScript.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published