selenium-webdriver: fix TargetLocator and logging (#42289)

* selenium-webdriver: move logging to separate file

* selenium-webdriver: fix TargetLocator type

* selenium-webdriver: fix test
This commit is contained in:
Ziyu 2020-02-15 04:17:44 +11:00 committed by GitHub
parent 46b1c41f67
commit 4b76dba9a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 443 additions and 396 deletions

View File

@ -22,6 +22,7 @@ import * as command from './lib/command';
import * as http from './http';
import { Actions, Button, Key, Origin } from './lib/input';
import { promise } from './lib/promise';
import * as logging from './lib/logging';
import * as until from './lib/until';
import * as safari from './safari';
@ -29,7 +30,8 @@ export { By, ByHash } from './lib/by';
export { Browser, Capability, Capabilities, ITimeouts } from './lib/capabilities';
export { Actions, Button, Key, Origin } from './lib/input';
export { promise } from './lib/promise';
export { until as until };
export { until };
export { logging };
/**
* Typings for lib/error
@ -306,347 +308,6 @@ export namespace error {
function encodeError(err: any): {error: string, message: string};
}
export namespace logging {
/**
* A hash describing log preferences.
* @typedef {Object.<logging.Type, logging.LevelName>}
*/
class Preferences {
setLevel(type: string, level: Level | string | number): void;
toJSON(): { [key: string]: string };
}
interface IType {
/** Logs originating from the browser. */
BROWSER: string;
/** Logs from a WebDriver client. */
CLIENT: string;
/** Logs from a WebDriver implementation. */
DRIVER: string;
/** Logs related to performance. */
PERFORMANCE: string;
/** Logs from the remote server. */
SERVER: string;
}
/**
* Common log types.
* @enum {string}
*/
const Type: IType;
/**
* Defines a message level that may be used to control logging output.
*
* @final
*/
class Level {
name_: string;
value_: number;
/**
* @param {string} name the level's name.
* @param {number} level the level's numeric value.
*/
constructor(name: string, level: number);
/** @override */
toString(): string;
/** This logger's name. */
name: string;
/** The numeric log level. */
value: number;
/**
* Indicates no log messages should be recorded.
* @const
*/
static OFF: Level;
/**
* Log messages with a level of `1000` or higher.
* @const
*/
static SEVERE: Level;
/**
* Log messages with a level of `900` or higher.
* @const
*/
static WARNING: Level;
/**
* Log messages with a level of `800` or higher.
* @const
*/
static INFO: Level;
/**
* Log messages with a level of `700` or higher.
* @const
*/
static DEBUG: Level;
/**
* Log messages with a level of `500` or higher.
* @const
*/
static FINE: Level;
/**
* Log messages with a level of `400` or higher.
* @const
*/
static FINER: Level;
/**
* Log messages with a level of `300` or higher.
* @const
*/
static FINEST: Level;
/**
* Indicates all log messages should be recorded.
* @const
*/
static ALL: Level;
}
/**
* Converts a level name or value to a {@link logging.Level} value.
* If the name/value is not recognized, {@link logging.Level.ALL}
* will be returned.
* @param {(number|string)} nameOrValue The log level name, or value, to
* convert .
* @return {!logging.Level} The converted level.
*/
function getLevel(nameOrValue: string | number): Level;
interface IEntryJSON {
level: string;
message: string;
timestamp: number;
type: string;
}
/**
* A single log entry.
*/
class Entry {
/**
* @param {(!logging.Level|string)} level The entry level.
* @param {string} message The log message.
* @param {number=} opt_timestamp The time this entry was generated, in
* milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the
* current time will be used.
* @param {string=} opt_type The log type, if known.
* @constructor
*/
constructor(level: Level | string | number, message: string, opt_timestamp?: number, opt_type?: string | IType);
/** @type {!logging.Level} */
level: Level;
/** @type {string} */
message: string;
/** @type {number} */
timestamp: number;
/** @type {string} */
type: string;
/**
* @return {{level: string, message: string, timestamp: number,
* type: string}} The JSON representation of this entry.
*/
toJSON(): IEntryJSON;
}
/**
* An object used to log debugging messages. Loggers use a hierarchical,
* dot-separated naming scheme. For instance, 'foo' is considered the parent of
* the 'foo.bar' and an ancestor of 'foo.bar.baz'.
*
* Each logger may be assigned a {@linkplain #setLevel log level}, which
* controls which level of messages will be reported to the
* {@linkplain #addHandler handlers} attached to this instance. If a log level
* is not explicitly set on a logger, it will inherit its parent.
*
* This class should never be directly instantiated. Instead, users should
* obtain logger references using the {@linkplain ./logging.getLogger()
* getLogger()} function.
*
* @final
*/
class Logger {
/**
* @param {string} name the name of this logger.
* @param {Level=} opt_level the initial level for this logger.
*/
constructor(name: string, opt_level?: Level);
/** @private {string} */
name_: string;
/** @private {Level} */
level_: Level;
/** @private {Logger} */
parent_: Logger;
/** @private {Set<function(!Entry)>} */
handlers_: any;
/** @return {string} the name of this logger. */
getName(): string;
/**
* @param {Level} level the new level for this logger, or `null` if the logger
* should inherit its level from its parent logger.
*/
setLevel(level: Level): void;
/** @return {Level} the log level for this logger. */
getLevel(): Level;
/**
* @return {!Level} the effective level for this logger.
*/
getEffectiveLevel(): Level;
/**
* @param {!Level} level the level to check.
* @return {boolean} whether messages recorded at the given level are loggable
* by this instance.
*/
isLoggable(level: Level): boolean;
/**
* Adds a handler to this logger. The handler will be invoked for each message
* logged with this instance, or any of its descendants.
*
* @param {function(!Entry)} handler the handler to add.
*/
addHandler(handler: any): void;
/**
* Removes a handler from this logger.
*
* @param {function(!Entry)} handler the handler to remove.
* @return {boolean} whether a handler was successfully removed.
*/
removeHandler(handler: any): void;
/**
* Logs a message at the given level. The message may be defined as a string
* or as a function that will return the message. If a function is provided,
* it will only be invoked if this logger's
* {@linkplain #getEffectiveLevel() effective log level} includes the given
* `level`.
*
* @param {!Level} level the level at which to log the message.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
log(level: Level, loggable: string | Function): void;
/**
* Logs a message at the {@link Level.SEVERE} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
severe(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.WARNING} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
warning(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.INFO} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
info(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.DEBUG} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
debug(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINE} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
fine(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINER} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
finer(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINEST} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
finest(loggable: string | Function): void;
}
/**
* Maintains a collection of loggers.
*
* @final
*/
class LogManager {
/**
* Retrieves a named logger, creating it in the process. This function will
* implicitly create the requested logger, and any of its parents, if they
* do not yet exist.
*
* @param {string} name the logger's name.
* @return {!Logger} the requested logger.
*/
getLogger(name?: string): Logger;
/**
* Creates a new logger.
*
* @param {string} name the logger's name.
* @param {!Logger} parent the logger's parent.
* @return {!Logger} the new logger.
* @private
*/
createLogger_(name: string, parent: Logger): Logger;
}
/**
* Retrieves a named logger, creating it in the process. This function will
* implicitly create the requested logger, and any of its parents, if they
* do not yet exist.
*
* @param {string} name the logger's name.
* @return {!Logger} the requested logger.
*/
function getLogger(name?: string): Logger;
/**
* Adds the console handler to the given logger. The console handler will log
* all messages using the JavaScript Console API.
*
* @param {Logger=} opt_logger The logger to add the handler to; defaults
* to the root logger.
*/
function addConsoleHandler(opt_logger?: Logger): void;
/**
* Removes the console log handler from the given logger.
*
* @param {Logger=} opt_logger The logger to remove the handler from; defaults
* to the root logger.
* @see exports.addConsoleHandler
*/
function removeConsoleHandler(opt_logger?: Logger): void;
}
/**
* Defines a condition for use with WebDriver's WebDriver#wait wait command.
*/
@ -1690,9 +1351,8 @@ export class TargetLocator {
defaultContent(): Promise<void>;
/**
* Schedules a command to switch the focus of all future commands to another
* frame on the page. The target frame may be specified as one of the
* following:
* Changes the focus of all future commands to another frame on the page. The
* target frame may be specified as one of the following:
*
* - A number that specifies a (zero-based) index into [window.frames](
* https://developer.mozilla.org/en-US/docs/Web/API/Window.frames).
@ -1708,7 +1368,17 @@ export class TargetLocator {
* @return {!Promise<void>} A promise that will be resolved
* when the driver has changed focus to the specified frame.
*/
frame(nameOrIndex: number|WebElement): Promise<void>;
frame(id: number|WebElement|null): Promise<void>;
/**
* Changes the focus of all future commands to the parent frame of the
* currently selected frame. This command has no effect if the driver is
* already focused on the top-level browsing context.
*
* @return {!Promise<void>} A promise that will be resolved when the command
* has completed.
*/
parentFrame(): Promise<void>;
/**
* Schedules a command to switch the focus of all future commands to another
@ -1725,6 +1395,19 @@ export class TargetLocator {
*/
window(nameOrHandle: string): Promise<void>;
/**
* Creates a new browser window and switches the focus for future
* commands of this driver to the new window.
*
* @param {string} typeHint 'window' or 'tab'. The created window is not
* guaranteed to be of the requested type; if the driver does not support
* the requested type, a new browser window will be created of whatever type
* the driver does support.
* @return {!Promise<void>} A promise that will be resolved
* when the driver has changed focus to the new window.
*/
newWindow(typeHint: string): Promise<void>;
/**
* Schedules a command to change focus to the active modal dialog, such as
* those opened by `window.alert()`, `window.confirm()`, and

View File

@ -0,0 +1,359 @@
/**
* Defines a message level that may be used to control logging output.
*
* @final
*/
export class Level {
name_: string;
value_: number;
/**
* @param {string} name the level's name.
* @param {number} level the level's numeric value.
*/
constructor(name: string, level: number);
/** @override */
toString(): string;
/** This logger's name. */
name: string;
/** The numeric log level. */
value: number;
/**
* Indicates no log messages should be recorded.
* @const
*/
static OFF: Level;
/**
* Log messages with a level of `1000` or higher.
* @const
*/
static SEVERE: Level;
/**
* Log messages with a level of `900` or higher.
* @const
*/
static WARNING: Level;
/**
* Log messages with a level of `800` or higher.
* @const
*/
static INFO: Level;
/**
* Log messages with a level of `700` or higher.
* @const
*/
static DEBUG: Level;
/**
* Log messages with a level of `500` or higher.
* @const
*/
static FINE: Level;
/**
* Log messages with a level of `400` or higher.
* @const
*/
static FINER: Level;
/**
* Log messages with a level of `300` or higher.
* @const
*/
static FINEST: Level;
/**
* Indicates all log messages should be recorded.
* @const
*/
static ALL: Level;
}
/**
* Converts a level name or value to a {@link logging.Level} value.
* If the name/value is not recognized, {@link logging.Level.ALL}
* will be returned.
* @param {(number|string)} nameOrValue The log level name, or value, to
* convert .
* @return {!logging.Level} The converted level.
*/
export function getLevel(nameOrValue: string | number): Level;
export interface IEntryJSON {
level: string;
message: string;
timestamp: number;
type: string;
}
/**
* A single log entry.
*/
export class Entry {
/**
* @param {(!logging.Level|string)} level The entry level.
* @param {string} message The log message.
* @param {number=} opt_timestamp The time this entry was generated, in
* milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the
* current time will be used.
* @param {string=} opt_type The log type, if known.
* @constructor
*/
constructor(level: Level | string | number, message: string, opt_timestamp?: number, opt_type?: string | IType);
/** @type {!logging.Level} */
level: Level;
/** @type {string} */
message: string;
/** @type {number} */
timestamp: number;
/** @type {string} */
type: string;
/**
* @return {{level: string, message: string, timestamp: number,
* type: string}} The JSON representation of this entry.
*/
toJSON(): IEntryJSON;
}
/**
* An object used to log debugging messages. Loggers use a hierarchical,
* dot-separated naming scheme. For instance, 'foo' is considered the parent of
* the 'foo.bar' and an ancestor of 'foo.bar.baz'.
*
* Each logger may be assigned a {@linkplain #setLevel log level}, which
* controls which level of messages will be reported to the
* {@linkplain #addHandler handlers} attached to this instance. If a log level
* is not explicitly set on a logger, it will inherit its parent.
*
* This class should never be directly instantiated. Instead, users should
* obtain logger references using the {@linkplain ./logging.getLogger()
* getLogger()} function.
*
* @final
*/
export class Logger {
/**
* @param {string} name the name of this logger.
* @param {Level=} opt_level the initial level for this logger.
*/
constructor(name: string, opt_level?: Level);
/** @private {string} */
name_: string;
/** @private {Level} */
level_: Level;
/** @private {Logger} */
parent_: Logger;
/** @private {Set<function(!Entry)>} */
handlers_: any;
/** @return {string} the name of this logger. */
getName(): string;
/**
* @param {Level} level the new level for this logger, or `null` if the logger
* should inherit its level from its parent logger.
*/
setLevel(level: Level): void;
/** @return {Level} the log level for this logger. */
getLevel(): Level;
/**
* @return {!Level} the effective level for this logger.
*/
getEffectiveLevel(): Level;
/**
* @param {!Level} level the level to check.
* @return {boolean} whether messages recorded at the given level are loggable
* by this instance.
*/
isLoggable(level: Level): boolean;
/**
* Adds a handler to this logger. The handler will be invoked for each message
* logged with this instance, or any of its descendants.
*
* @param {function(!Entry)} handler the handler to add.
*/
addHandler(handler: any): void;
/**
* Removes a handler from this logger.
*
* @param {function(!Entry)} handler the handler to remove.
* @return {boolean} whether a handler was successfully removed.
*/
removeHandler(handler: any): void;
/**
* Logs a message at the given level. The message may be defined as a string
* or as a function that will return the message. If a function is provided,
* it will only be invoked if this logger's
* {@linkplain #getEffectiveLevel() effective log level} includes the given
* `level`.
*
* @param {!Level} level the level at which to log the message.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
log(level: Level, loggable: string | Function): void;
/**
* Logs a message at the {@link Level.SEVERE} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
severe(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.WARNING} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
warning(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.INFO} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
info(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.DEBUG} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
debug(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINE} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
fine(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINER} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
finer(loggable: string | Function): void;
/**
* Logs a message at the {@link Level.FINEST} log level.
* @param {(string|function(): string)} loggable the message to log, or a
* function that will return the message.
*/
finest(loggable: string | Function): void;
}
/**
* Maintains a collection of loggers.
*
* @final
*/
export class LogManager {
/**
* Retrieves a named logger, creating it in the process. This function will
* implicitly create the requested logger, and any of its parents, if they
* do not yet exist.
*
* @param {string} name the logger's name.
* @return {!Logger} the requested logger.
*/
getLogger(name?: string): Logger;
/**
* Creates a new logger.
*
* @param {string} name the logger's name.
* @param {!Logger} parent the logger's parent.
* @return {!Logger} the new logger.
* @private
*/
createLogger_(name: string, parent: Logger): Logger;
}
/**
* Retrieves a named logger, creating it in the process. This function will
* implicitly create the requested logger, and any of its parents, if they
* do not yet exist.
*
* @param {string} name the logger's name.
* @return {!Logger} the requested logger.
*/
export function getLogger(name?: string): Logger;
/**
* Adds the console handler to the given logger. The console handler will log
* all messages using the JavaScript Console API.
*
* @param {Logger=} opt_logger The logger to add the handler to; defaults
* to the root logger.
*/
export function addConsoleHandler(opt_logger?: Logger): void;
/**
* Removes the console log handler from the given logger.
*
* @param {Logger=} opt_logger The logger to remove the handler from; defaults
* to the root logger.
* @see exports.addConsoleHandler
*/
export function removeConsoleHandler(opt_logger?: Logger): void;
/**
* Installs the console log handler on the root logger.
*/
export function installConsoleHandler(): void;
export interface IType {
/** Logs originating from the browser. */
BROWSER: string;
/** Logs from a WebDriver client. */
CLIENT: string;
/** Logs from a WebDriver implementation. */
DRIVER: string;
/** Logs related to performance. */
PERFORMANCE: string;
/** Logs from the remote server. */
SERVER: string;
}
/**
* Common log types.
* @enum {string}
*/
export const Type: IType;
/**
* Describes the log preferences for a WebDriver session.
*/
export class Preferences {
prefs_: Map<string, Level>;
constructor();
/**
* Sets the desired logging level for a particular log type.
* @param {(string|Type)} type The log type.
* @param {(!Level|string|number)} level The desired log level.
* @throws {TypeError} if `type` is not a `string`.
*/
setLevel(type: string | IType, level: Level): void;
/**
* Converts this instance to its JSON representation.
* @return {!Object<string, string>} The JSON representation of this set of
* preferences.
*/
toJSON(): { [key: string]: string };
}

View File

@ -361,7 +361,9 @@ function TestWebDriverTargetLocator() {
let alert: webdriver.Alert = locator.alert();
promise = locator.defaultContent();
promise = locator.frame(1);
promise = locator.parentFrame();
promise = locator.window('nameOrHandle');
promise = locator.newWindow('tab');
}
function TestWebDriverWindow() {
@ -522,55 +524,6 @@ function TestWebElementPromise() {
elementPromise.then((element: webdriver.WebElement) => 'foo', (error: any) => 'bar').then((result: string) => {});
}
function TestLogging() {
let preferences: webdriver.logging.Preferences = new webdriver.logging.Preferences();
preferences.setLevel(webdriver.logging.Type.BROWSER, webdriver.logging.Level.ALL);
let prefs: any = preferences.toJSON();
let level: webdriver.logging.Level = webdriver.logging.getLevel('OFF');
level = webdriver.logging.getLevel(1);
level = webdriver.logging.Level.ALL;
level = webdriver.logging.Level.DEBUG;
level = webdriver.logging.Level.INFO;
level = webdriver.logging.Level.OFF;
level = webdriver.logging.Level.SEVERE;
level = webdriver.logging.Level.WARNING;
let name: string = level.name;
let value: number = level.value;
let type: string;
type = webdriver.logging.Type.BROWSER;
type = webdriver.logging.Type.CLIENT;
type = webdriver.logging.Type.DRIVER;
type = webdriver.logging.Type.PERFORMANCE;
type = webdriver.logging.Type.SERVER;
let logger: webdriver.logging.Logger = webdriver.logging.getLogger();
webdriver.logging.addConsoleHandler();
webdriver.logging.addConsoleHandler(logger);
webdriver.logging.removeConsoleHandler();
webdriver.logging.removeConsoleHandler(logger);
}
function TestLoggingEntry() {
let entry: webdriver.logging.Entry;
entry = new webdriver.logging.Entry(webdriver.logging.Level.ALL, 'ABC');
entry = new webdriver.logging.Entry('ALL', 'ABC');
entry = new webdriver.logging.Entry(webdriver.logging.Level.ALL, 'ABC', 123);
entry = new webdriver.logging.Entry('ALL', 'ABC', 123);
entry = new webdriver.logging.Entry(webdriver.logging.Level.ALL, 'ABC', 123, webdriver.logging.Type.BROWSER);
entry = new webdriver.logging.Entry('ALL', 'ABC', 123, webdriver.logging.Type.BROWSER);
let entryObj: any = entry.toJSON();
let message: string = entry.message;
let timestamp: number = entry.timestamp;
let type: string = entry.type;
}
declare let stringPromise: Promise<string>;
function TestUntilModule() {

View File

@ -0,0 +1,51 @@
import { addConsoleHandler, Entry, getLevel, getLogger, installConsoleHandler, Level, Logger, Preferences, removeConsoleHandler, Type } from 'selenium-webdriver/lib/logging';
function TestLogging() {
let preferences: Preferences = new Preferences();
preferences.setLevel(Type.BROWSER, Level.ALL);
let prefs: any = preferences.toJSON();
let level: Level = getLevel('OFF');
level = getLevel(1);
level = Level.ALL;
level = Level.DEBUG;
level = Level.INFO;
level = Level.OFF;
level = Level.SEVERE;
level = Level.WARNING;
let name: string = level.name;
let value: number = level.value;
let type: string;
type = Type.BROWSER;
type = Type.CLIENT;
type = Type.DRIVER;
type = Type.PERFORMANCE;
type = Type.SERVER;
let logger: Logger = getLogger();
addConsoleHandler();
addConsoleHandler(logger);
removeConsoleHandler();
removeConsoleHandler(logger);
installConsoleHandler();
}
function TestLoggingEntry() {
let entry: Entry;
entry = new Entry(Level.ALL, 'ABC');
entry = new Entry('ALL', 'ABC');
entry = new Entry(Level.ALL, 'ABC', 123);
entry = new Entry('ALL', 'ABC', 123);
entry = new Entry(Level.ALL, 'ABC', 123, Type.BROWSER);
entry = new Entry('ALL', 'ABC', 123, Type.BROWSER);
let entryObj: any = entry.toJSON();
let message: string = entry.message;
let timestamp: number = entry.timestamp;
let type: string = entry.type;
}

View File

@ -23,6 +23,7 @@
"test/index.ts",
"test/chrome.ts",
"test/firefox.ts",
"test/remote.ts"
"test/remote.ts",
"test/logging.ts"
]
}