summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/test/browser_mdn-docs-01.js
blob: 6490dfef7103fdc33b09212bf9cd6d543aac72c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * This file tests the MdnDocsWidget object, and specifically its
 * loadCssDocs() function.
 *
 * The MdnDocsWidget is initialized with a document which has a specific
 * structure. You then call loadCssDocs(), passing in a CSS property name.
 * MdnDocsWidget then fetches docs for that property by making an XHR to
 * a docs page, and loads the results into the document. While the XHR is
 * still not resolved the document is put into an "initializing" state in
 * which the devtools throbber is displayed.
 *
 * In this file we test:
 * - the initial state of the document before the docs have loaded
 * - the state of the document after the docs have loaded
 */

"use strict";

const {setBaseCssDocsUrl, MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget");

/**
 * Test properties
 *
 * In the real tooltip, a CSS property name is used to look up an MDN page
 * for that property.
 * In the test code, the names defined here is used to look up a page
 * served by the test server.
 */
const BASIC_TESTING_PROPERTY = "html-mdn-css-basic-testing.html";

const BASIC_EXPECTED_SUMMARY = "A summary of the property.";
const BASIC_EXPECTED_SYNTAX = [{type: "comment", text: "/* The part we want   */"},
                               {type: "text", text: "\n"},
                               {type: "property-name", text: "this"},
                               {type: "text", text: ":"},
                               {type: "text", text: " "},
                               {type: "property-value", text: "is-the-part-we-want"},
                               {type: "text", text: ";"}];

const URI_PARAMS =
  "?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default";

add_task(function* () {
  setBaseCssDocsUrl(TEST_URI_ROOT);

  yield addTab("about:blank");
  let [host, win] = yield createHost("bottom", "data:text/html," +
    "<div class='mdn-container'></div>");
  let widget = new MdnDocsWidget(win.document.querySelector("div"));

  yield testTheBasics(widget);

  host.destroy();
  gBrowser.removeCurrentTab();
});

/**
 * Test all the basics
 * - initial content, before docs have loaded, is as expected
 * - throbber is set before docs have loaded
 * - contents are as expected after docs have loaded
 * - throbber is gone after docs have loaded
 * - mdn link text is correct and onclick behavior is correct
 */
function* testTheBasics(widget) {
  info("Test all the basic functionality in the widget");

  info("Get the widget state before docs have loaded");
  let promise = widget.loadCssDocs(BASIC_TESTING_PROPERTY);

  info("Check initial contents before docs have loaded");
  checkTooltipContents(widget.elements, {
    propertyName: BASIC_TESTING_PROPERTY,
    summary: "",
    syntax: ""
  });

  // throbber is set
  ok(widget.elements.info.classList.contains("devtools-throbber"),
     "Throbber is set");

  info("Now let the widget finish loading");
  yield promise;

  info("Check contents after docs have loaded");
  checkTooltipContents(widget.elements, {
    propertyName: BASIC_TESTING_PROPERTY,
    summary: BASIC_EXPECTED_SUMMARY,
    syntax: BASIC_EXPECTED_SYNTAX
  });

  // throbber is gone
  ok(!widget.elements.info.classList.contains("devtools-throbber"),
     "Throbber is not set");

  info("Check that MDN link text is correct and onclick behavior is correct");

  let mdnLink = widget.elements.linkToMdn;
  let expectedHref = TEST_URI_ROOT + BASIC_TESTING_PROPERTY + URI_PARAMS;
  is(mdnLink.href, expectedHref, "MDN link href is correct");

  let uri = yield checkLinkClick(mdnLink);
  is(uri, expectedHref, "New tab opened with the expected URI");
}

 /**
  * Clicking the "Visit MDN Page" in the tooltip panel
  * should open a new browser tab with the page loaded.
  *
  * To test this we'll listen for a new tab opening, and
  * when it does, add a listener to that new tab to tell
  * us when it has loaded.
  *
  * Then we click the link.
  *
  * In the tab's load listener, we'll resolve the promise
  * with the URI, which is expected to match the href
  * in the orginal link.
  *
  * One complexity is that when you open a new tab,
  * "about:blank" is first loaded into the tab before the
  * actual page. So we ignore that first load event, and keep
  * listening until "load" is triggered for a different URI.
  */
function checkLinkClick(link) {
  function loadListener(tab) {
    let browser = getBrowser().getBrowserForTab(tab);
    let uri = browser.currentURI.spec;

    info("New browser tab has loaded");
    gBrowser.removeTab(tab);
    info("Resolve promise with new tab URI");
    deferred.resolve(uri);
  }

  function newTabListener(e) {
    gBrowser.tabContainer.removeEventListener("TabOpen", newTabListener);
    let tab = e.target;
    BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url => url != "about:blank")
      .then(url => loadListener(tab));
  }

  let deferred = defer();
  info("Check that clicking the link opens a new tab with the correct URI");
  gBrowser.tabContainer.addEventListener("TabOpen", newTabListener, false);
  info("Click the link to MDN");
  link.click();
  return deferred.promise;
}

/**
 * Utility function to check content of the tooltip.
 */
function checkTooltipContents(doc, expected) {
  is(doc.heading.textContent,
     expected.propertyName,
     "Property name is correct");

  is(doc.summary.textContent,
     expected.summary,
     "Summary is correct");

  checkCssSyntaxHighlighterOutput(expected.syntax, doc.syntax);
}