/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";

// Tests for menuitem functionality that doesn't fit into any specific category
const TEST_URL = URL_ROOT + "doc_inspector_menu.html";
add_task(function* () {
  let { inspector, toolbox, testActor } = yield openInspectorForURL(TEST_URL);
  yield testShowDOMProperties();
  yield testDuplicateNode();
  yield testDeleteNode();
  yield testDeleteTextNode();
  yield testDeleteRootNode();
  yield testScrollIntoView();
  function* testShowDOMProperties() {
    info("Testing 'Show DOM Properties' menu item.");
    let allMenuItems = openContextMenuAndGetAllItems(inspector);
    let showDOMPropertiesNode =
      allMenuItems.find(item => item.id === "node-menu-showdomproperties");
    ok(showDOMPropertiesNode, "the popup menu has a show dom properties item");

    let consoleOpened = toolbox.once("webconsole-ready");

    info("Triggering 'Show DOM Properties' and waiting for inspector open");
    showDOMPropertiesNode.click();
    yield consoleOpened;

    let webconsoleUI = toolbox.getPanel("webconsole").hud.ui;
    let messagesAdded = webconsoleUI.once("new-messages");
    yield messagesAdded;
    info("Checking if 'inspect($0)' was evaluated");
    ok(webconsoleUI.jsterm.history[0] === "inspect($0)");
    yield toolbox.toggleSplitConsole();
  }
  function* testDuplicateNode() {
    info("Testing 'Duplicate Node' menu item for normal elements.");

    yield selectNode(".duplicate", inspector);
    is((yield testActor.getNumberOfElementMatches(".duplicate")), 1,
       "There should initially be 1 .duplicate node");

    let allMenuItems = openContextMenuAndGetAllItems(inspector);
    let menuItem =
      allMenuItems.find(item => item.id === "node-menu-duplicatenode");
    ok(menuItem, "'Duplicate node' menu item should exist");

    info("Triggering 'Duplicate Node' and waiting for inspector to update");
    let updated = inspector.once("markupmutation");
    menuItem.click();
    yield updated;

    is((yield testActor.getNumberOfElementMatches(".duplicate")), 2,
       "The duplicated node should be in the markup.");

    let container = yield getContainerForSelector(".duplicate + .duplicate",
                                                   inspector);
    ok(container, "A MarkupContainer should be created for the new node");
  }

  function* testDeleteNode() {
    info("Testing 'Delete Node' menu item for normal elements.");
    yield selectNode("#delete", inspector);
    let allMenuItems = openContextMenuAndGetAllItems(inspector);
    let deleteNode = allMenuItems.find(item => item.id === "node-menu-delete");
    ok(deleteNode, "the popup menu has a delete menu item");
    let updated = inspector.once("inspector-updated");

    info("Triggering 'Delete Node' and waiting for inspector to update");
    deleteNode.click();
    yield updated;

    ok(!(yield testActor.hasNode("#delete")), "Node deleted");
  }

  function* testDeleteTextNode() {
    info("Testing 'Delete Node' menu item for text elements.");
    let { walker } = inspector;
    let divBefore = yield walker.querySelector(walker.rootNode, "#nestedHiddenElement");
    let { nodes } = yield walker.children(divBefore);
    yield selectNode(nodes[0], inspector, "test-highlight");

    let allMenuItems = openContextMenuAndGetAllItems(inspector);
    let deleteNode = allMenuItems.find(item => item.id === "node-menu-delete");
    ok(deleteNode, "the popup menu has a delete menu item");
    ok(deleteNode.disabled == false, "the delete menu item is not disabled");
    let updated = inspector.once("inspector-updated");

    info("Triggering 'Delete Node' and waiting for inspector to update");
    deleteNode.click();
    yield updated;

    let divAfter = yield walker.querySelector(walker.rootNode, "#nestedHiddenElement");
    let nodesAfter = (yield walker.children(divAfter)).nodes;
    ok(nodesAfter.length == 0, "the node still had children");
  }

  function* testDeleteRootNode() {
    info("Testing 'Delete Node' menu item does not delete root node.");
    yield selectNode("html", inspector);

    let allMenuItems = openContextMenuAndGetAllItems(inspector);
    let deleteNode = allMenuItems.find(item => item.id === "node-menu-delete");
    deleteNode.click();

    yield new Promise(resolve => {
      executeSoon(resolve);
    });

    ok((yield testActor.eval("!!document.documentElement")),
       "Document element still alive.");
  }

  function* testScrollIntoView() {
    // Follow up bug to add this test - https://bugzilla.mozilla.org/show_bug.cgi?id=1154107
    todo(false, "Verify that node is scrolled into the viewport.");
  }
});
