// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// See //extensions/docs/testing_api.md for how to use this API.
[
  {
    "namespace": "test",
    "description": "none",
    "functions": [
      {
        "name": "getConfig",
        "type": "function",
        "description": "Gives configuration options set by the test.",
        "parameters": [],
        "returns_async": {
          "name": "callback",
          "parameters": [
            {
              "type": "object",
              "name": "testConfig",
              "properties": {
                "customArg": {
                  "type": "string",
                  "optional": true,
                  "description": "Additional string argument to pass to test."
                },
                "ftpServer": {
                  "type": "object",
                  "optional": true,
                  "description": "Details on the FTP server used to mock network responses.  Will be set only if test calls ExtensionApiTest::StartFTPServer().",
                  "properties": {
                    "port": {
                      "type": "integer",
                      "description": "The port on which the FTP server is listening.",
                      "minimum": 1024,
                      "maximum": 65535
                    }
                  }
                },
                "testServer": {
                  "type": "object",
                  "optional": true,
                  "description": "Details on the test server used to mock network responses.  Will be set only if test calls ExtensionApiTest::StartEmbeddedTestServer().",
                  "properties": {
                    "port": {
                      "type": "integer",
                      "description": "The port on which the test server is listening.",
                      "minimum": 1024,
                      "maximum": 65535
                    }
                  }
                },
                "testDataDirectory": {
                  "type": "string",
                  "optional": true,
                  "description": "file:/// URL for the API test data directory."
                },
                "testWebSocketPort": {
                  "type": "integer",
                  "optional": true,
                  "description": "The port on which the test WebSocket server is listening.",
                  "minimum": 0,
                  "maximum": 65535
                },
                "testWebTransportPort": {
                  "type": "integer",
                  "optional": true,
                  "description": "The port on which the test WebTransport server is listening.",
                  "minimum": 0,
                  "maximum": 65535
                },
                "loginStatus": {
                  "type": "object",
                  "optional": true,
                  "description": "Login status.",
                  "properties": {
                    "isLoggedIn": {
                      "type": "boolean",
                      "optional": true,
                      "description": "Whether there's a logged-in user."
                    },
                    "isScreenLocked": {
                      "type": "boolean",
                      "optional": true,
                      "description": "Whether the screen is locked."
                    }
                  }
                }
              }
            }
          ]
        }
      },
      {
        "name": "notifyFail",
        "type": "function",
        "description": "Notifies the browser process that test code running in the extension failed.  This is only used for internal unit testing.",
        "parameters": [
          {"type": "string", "name": "message"}
        ]
      },
      {
        "name": "notifyPass",
        "type": "function",
        "description": "Notifies the browser process that test code running in the extension passed.  This is only used for internal unit testing.",
        "parameters": [
          {"type": "string", "name": "message", "optional": true}
        ]
      },
      {
        "name": "log",
        "type": "function",
        "description": "Logs a message during internal unit testing.",
        "parameters": [
          {"type": "string", "name": "message"}
        ]
      },
      {
        "name": "openFileUrl",
        "type": "function",
        "description": "Open file: URLs for tests.",
        "parameters": [
          {"type": "string", "name": "url"}
        ]
      },
      {
        "name": "sendMessage",
        "type": "function",
        "description": "Sends a string message to the browser process, generating a Notification that C++ test code can wait for.",
        "parameters": [
          {"type": "string", "name": "message"}
        ],
        "returns_async": {
          "name": "callback",
          "optional": true,
          "parameters": [
            {"type": "string", "name": "response"}
          ]
        }
      },
      {
        "name": "sendScriptResult",
        "type": "function",
        "description": "Sends a result back to the browser as a result of script executing; this is handy for communicating results from browser-driven script execution.",
        "parameters": [{"type": "any", "name": "result"}],
        "returns_async": {
          "name": "callback",
          "optional": true,
          "parameters": []
        }
      },
      {
        "name": "notifyTestStarted",
        "type": "function",
        "description": "Notifies the browser process that a specific test case in the test code started running. The chrome.test API uses this internally.",
        "parameters": [
          {
            "type": "string",
            "name": "testName"
          }
        ]
      },
      {
        "name": "notifyTestFinished",
        "type": "function",
        "description": "Notifies the browser process that a specific test case in the test code finished running. The chrome.test API uses this internally.",
        "parameters": [
          {
            "type": "string",
            "name": "testName"
          },
          {
            "type": "boolean",
            "name": "result"
          },
          {
            "type": "integer",
            "name": "remainingTests"
          },
          {
            "type": "string",
            "name": "assertionDescription"
          },
          {
            "type": "string",
            "name": "message",
            "optional": true
          }
        ]
      },
      {
        "name": "callbackAdded",
        "type": "function",
        "nocompile": true,
        "parameters": []
      },
      {
        "name": "fail",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "any", "name": "message", "optional": true}
        ]
      },
      {
        "name": "succeed",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "any", "name": "message", "optional": true}
        ]
      },
      {
        "name": "getModuleSystem",
        "type": "function",
        "nocompile": true,
        "description": "Returns an instance of the module system for the given context.",
        "parameters": [
          {
            "type": "any",
            "name": "context"
          }
        ],
        "returns": {
          "type": "any",
          "description": "The module system",
          "optional": true
        }
      },
      {
        "name": "assertTrue",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {
            "name": "test",
            "type": "boolean"
          },
          {"type": "string", "name": "message", "optional": true}
        ]
      },
      {
        "name": "assertFalse",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {
            "name": "test",
            "type": "boolean"
          },
          {"type": "string", "name": "message", "optional": true}
        ]
      },
      {
        "name": "checkDeepEq",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "any", "name": "value", "optional": true},
          {"type": "any", "name": "other_value", "optional": true}
        ]
      },
      {
        "name": "assertEq",
        "type": "function",
        "nocompile": true,
        "parameters": [
          // These need to be optional because they can be null.
          {"type": "any", "name": "value", "optional": true},
          {"type": "any", "name": "other_value", "optional": true},
          {
            "type": "string",
            "name": "message",
            "optional": true,
            "description": "A custom error message to print out with the test failure, if any."
          }
        ]
      },
      {
        "name": "assertNe",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "any", "name": "value", "optional": true},
          {"type": "any", "name": "other_value", "optional": true},
          {
            "type": "string",
            "name": "message",
            "optional": true,
            "description": "A custom error message to print out with the test failure, if any."
          }
        ]
      },
      {
        "name": "assertNoLastError",
        "type": "function",
        "nocompile": true,
        "parameters": []
      },
      {
        "name": "assertLastError",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "string", "name": "expectedError"}
        ]
      },
      {
        "name": "assertThrows",
        "type": "function",
        "nocompile": true,
        "description": "Asserts that a given function throws an error. If it does not, or if the thrown error doesn't match expectedError (if defined), the test fails.",
        "parameters": [
          {"type": "function", "name": "fn"},
          {
            "choices": [
              {"type": "string"},
              {"type": "object", "isInstanceOf": "RegExp"}
            ],
            "name": "expectedError",
            "optional": true,
            "description": "Expected error message or RegExp."
          },
          {
            "type": "string",
            "name": "message",
            "optional": true,
            "description": "Custom failure message."
          }
        ]
      },
      {
        "name": "assertPromiseRejects",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {
            "type": "object",
            "name": "promise",
            "isInstanceOf": "Promise",
            "description": "The promise to evaluate, which is expected to reject."
          },
          {
            "choices": [
              {"type": "string"},
              {"type": "object", "isInstanceOf": "RegExp"}
            ],
            "name": "expectedMessage",
            "description": "The expected error message from the promise rejection, either as a string or a regular expression."
          }
        ],
        "returns": {
          "type": "object",
          "isInstanceOf": "Promise",
          "description": "A promise that will be resolved once the assertion is complete. The promise is rejected if the passed-in promise resolves unexpectedly or rejects with an unexpected error."
        }
      },
      {
        "name": "callback",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "function", "name": "func", "optional": true},
          {"type": "string", "name": "expectedError", "optional": true}
        ]
      },
      {
        "name": "listenOnce",
        "description": "Listens to the given event exactly once. This will add a new event listener and remove it after its first invocation. If supplied a function argument, this will add a pending callback to the test so that it won't automatically complete until invoked (see also callbackPass()). If no function is supplied, this returns a promise and does not artifically prolong the lifetime of the test.",
        "type": "function",
        "nocompile": true,
        "parameters": [
          // TODO(cduvall): Make this a $ref to events.Event.
          {"type": "any", "name": "event"},
          {
            "type": "function",
            "name": "func",
            "optional": true,
            "description": "If provided, a function to invoke with the arugments that the event was triggered with."
          }
        ],
        "returns": {
          "type": "object",
          "isInstanceOf": "Promise",
          "optional": true,
          "description": "A promise that will be resolved when the event has been triggered, and will be resolved with the arguments passed to the event. Clunkily, if only a single argument is passed to the event (common case), the promise will be invoked with that single argument. If multiple arguments are passed to the event, the promise will be resolved with an array of arguments. This is only returned if a function argument is *not* passed to listenOnce()."
        }
      },
      {
        "name": "listenForever",
        "type": "function",
        "nocompile": true,
        "parameters": [
          // TODO(cduvall): Make this a $ref to events.Event.
          {"type": "any", "name": "event"},
          {"type": "function", "name": "func"}
        ]
      },
      {
        "name": "callbackPass",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "function", "name": "func", "optional": true}
        ]
      },
      {
        "name": "callbackFail",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {"type": "string", "name": "expectedError"},
          {"type": "function", "name": "func", "optional": true}
        ]
      },
      {
        "name": "runTests",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {
            "type": "array",
            "name": "tests",
            "items": {"type": "function"}
          }
        ],
        "returns": {
          "type": "object",
          "isInstanceOf": "Promise",
          "description": "A promise that resolves when all tests complete successfully or rejects if any test failed."
        }
      },
      {
        "name": "getApiFeatures",
        "type": "function",
        "nocompile": true,
        "parameters": []
      },
      {
        "name": "getApiDefinitions",
        "type": "function",
        "nocompile": true,
        "parameters": [
          {
            "type": "array",
            "name": "apiNames",
            "optional": true,
            "items": {"type": "string"}
          }
        ]
      },
      {
        "name": "isProcessingUserGesture",
        "type": "function",
        "nocompile": true,
        "parameters": []
      },
      {
        "name": "runWithUserGesture",
        "type": "function",
        "description": "Runs the provided function in the context of a user gesture.",
        "nocompile": true,
        "parameters": [
          {
            "type": "function",
            "name": "functionToRun",
            "parameters": []
          }
        ]
      },
      {
        "name": "waitForRoundTrip",
        "type": "function",
        "description": "Sends a string message one round trip from the renderer to the browser process and back.",
        "parameters": [
          {"type": "string", "name": "message"}
        ],
        "returns_async": {
          "name": "callback",
          "parameters": [
            {"type": "string", "name": "message"}
          ]
        }
      },
      {
        "name": "loadScript",
        "type": "function",
        "nocompile": true,
        "description": "Loads a JS script in the current JS context.",
        "parameters": [
          {
            "type": "string",
            "name": "scriptUrl"
          }
        ],
        "returns": {
          "type": "object",
          "isInstanceOf": "Promise",
          "description": "A promise that will be resolved once the script is loaded."
        }
      },
      {
        "name": "setExceptionHandler",
        "type": "function",
        "description": "Sets the function to be called when an exception occurs. By default this is a function which fails the test. This is reset for every test run through $ref:test.runTests.",
        "nocompile": true,
        "parameters": [
          {
            "type": "function",
            "name": "handler",
            "parameters": [
              {"type": "string", "name": "message"},
              {"type": "any", "name": "exception"}
            ]
          }
        ]
      }
    ],
    "events": [
      {
        "name": "onMessage",
        "type": "function",
        "description": "Used to test sending messages to extensions.",
        "parameters": [
          {
            "type": "object",
            "name": "info",
            "properties": {
              "data": { "type": "string", "description": "Additional information." },
              "lastMessage": { "type": "boolean", "description": "True if this was the last message for this test" }
            }
          }
        ]
      },
      {
        "name": "onTestStarted",
        "type": "function",
        "description": "Fired when a test is started, before any test logic has run.",
        "parameters": [
          {
            "type": "object",
            "name": "info",
            "properties": {
              "testName": { "type": "string" }
            }
          }
        ]
      },
      {
        "name": "onTestFinished",
        "type": "function",
        "description": "Fired when a test evaluates to success or failure.",
        "parameters": [
          {
            "type": "object",
            "name": "info",
            "properties": {
              "testName": { "type": "string" },
              "result": { "type": "boolean" },
              "remainingTests": { "type": "integer" },
              "assertionDescription": { "type": "string" },
              "message": { "type": "string", "optional": true }
            }
          }
        ]
      }
    ]
  }
]
