Passing the Tech Test

@oliverturner

Director of Education @ConstructorLabs

What is a tech test?

What is a tech test?

    1. Communication
    2. Focus
    3. Ability

  • Empathy
  • Comprehension
  • Communication
  • Execution

summary

CASE STUDY 1

import Model from "./model.mjs";
import View from "./view.mjs";

class App {
  constructor(options) {
    this.model = new Model(options.model);
    this.view = new View(
      Object.assign({}, options.view, {
        handlers: { onSearch: this.onSearch.bind(this) }
      })
    );

    this.initialise();
  }

  async initialise() {
    const { ok, records, err } = await this.model.loadData();

    ok ? this.view.display(records) : this.view.displayError(err);
  }

  onSearch(event) {
    event.preventDefault();
    const term = event.target.searchterm.value;
    const results = this.model.filter(term);
    this.view.display(results);
  }
}

export default App;
class Model {
  ...

  parseHTML(html) {
    const div = document.createElement("div");
    div.innerHTML = html.trim();
    return div;
  }

  /**
   * Grab the HTML of the target document via AJAX
   * Return a queryable DOM node from the returned string
   */
  fetchData() {
    const { url, parser } = this.options;
    return fetch(`https://cors-anywhere.herokuapp.com/${url}`, {
      headers: { "X-Requested-With": "Panache" }
    })
      .then(res => (res.ok ? res.text() : Promise.reject(res.err)))
      .then(str => parser(this.parseHTML(str)))
      .catch(err => err);
  }

  filter(term) {
    term = term.toLowerCase();
    return this.state.records.filter(record =>
      record.label.toLowerCase().includes(term)
    );
  }
}

export default Model;
// type Record = {href: string, label: string}

export default {
  url: "whatsonnetflix.com/netflix-hacks/the-netflix-id-bible-every-category-on-netflix/",
  parser: function(el) {
    const nodeList = el.querySelectorAll(".articleBody p");

    // Extract genre objects into an array, then use a dict to dedupe by id
    // => {[id: string]: Record}
    const records = Array.from(nodeList)
      .filter(node => '/^\d{1,6} = [\w &;]+/'.test(node.textContent))
      .reduce((acc, node) => {
        const [id, label] = node.textContent.split(" = ");
        const href = `http://www.netflix.com/browse/genre/${id}`;

        return Object.assign({}, acc, { [id]: { href, label } });
      }, {});

    // Return an array of records alphabetically sorted by label
    // => Record[]
    return Object.values(records).sort((a, b) => b.label < a.label);
  }
};
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Unfathomable</title>
  <link rel="stylesheet" href="./styles.css">
</head>

<body>
  <div class="app is-loading" id="app">
    <form action="{URL}" class="search">
      <div class="search__content">
        <label for="searchterm" class="search__label">Search:</label>
        <input id="searchterm" name="searchterm" class="search__term" autofocus="">
      </div>
    </form>
    
    <div class="content"></div>
  </div>

  <script type="module">
    import App from "./modules/index.js"
    import model from "./modules/parsers/netflix.js"

    const app = new App({ model, view: { root: document.querySelector("#app") } })
  </script>
  <script src="./no-module.js" defer nomodule></script>
</body>

</html>

points to note

  • Supported in all evergreen browsers
  • Must specify extension in Node >= 10
  • .mjs files need valid content-type set
  • Link rel=preload cannot be used :(
  • Automatically deferred & non-blocking: ES6 modules are loaded and executed asynchronously after the browser finished parsing the HTML.
  • ES6 modules run in strict mode by default (no need for 'use strict' anymore).
  • Top-level value of `this` is `undefined`.
  • Top-level variables are local to the module.

CASE STUDY 2

Now what?

What is a tech test?

Conclusion

  1. An exercise in empathy
  2. Messy, human communication
  3. Not the end of the world
  4. Potentially fun!
  5. Don't forget: we want you to succeed!

Passing the Tech Test

By Oliver Turner

Passing the Tech Test

  • 738