Added files for Juan

This commit is contained in:
2024-08-07 11:38:48 -07:00
parent f7878e3e60
commit 795d1d72ce
2871 changed files with 621552 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
Copyright (c) OpenJS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,72 @@
WDIO Logger Utility
===================
> A helper utility for logging of WebdriverIO packages
This package is used across all WebdriverIO packages to log information using the [`loglevel`](https://www.npmjs.com/package/loglevel) package. It can also be used for any other arbitrary Node.js project.
## Install
To install the package just call
```sh
npm install @wdio/logger
```
or when adding it to a WebdriverIO subpackage:
```sh
lerna add @wdio/logger --scope <subpackage>
```
## Usage
The package exposes a logger function that you can use to register an instance for your scoped package:
```js
import logger from '@wdio/logger'
const log = logger('myPackage')
log.info('some logs')
```
For more info see [`loglevel`](https://www.npmjs.com/package/loglevel) package on NPM.
## Custom Log Levels
This package extends the log levels available in [`loglevel`](https://www.npmjs.com/package/loglevel) by introducing a new level called `progress`.
The `progress` level is particularly useful when you need to dynamically update a specific line in the terminal. For example, it can be utilized to display the download progress of browsers or drivers.
Notably, the `progress` level is equivalent to the `info` level. Therefore, if you set the log level to `error` or `silent`, any `progress` logs will be suppressed.
It's important to mention that `progress` writes directly to `process.stdout`, and these logs won't be captured in any log files.
To ensure consistent formatting with subsequent logs while using `progress`, it's essential to clear it at the end. To do so, simply call `progress` with an empty string, which will clear the last line:
```
log.progress('')
```
### Illustrative Usage of Progress
```javascript
import logger from '@wdio/logger';
const log = logger('internal');
const totalSize = 100;
let uploadedSize = 0;
const uploadInterval = setInterval(() => {
const chunkSize = 10;
uploadedSize += chunkSize;
const data = `Progress: ${(uploadedSize * 100) / totalSize}%`;
log.progress(data);
if (uploadedSize >= totalSize) {
clearInterval(uploadInterval);
log.progress(''); // Called at the end to maintain the alignment of subsequent logs.
console.log('Upload complete.');
}
}, 100);
```

View File

@@ -0,0 +1,5 @@
import type loggerType from './node.js';
export type { Logger } from './node.js';
declare const _default: typeof loggerType;
export default _default;
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;;AAqBvC,wBAAgD"}

View File

@@ -0,0 +1,19 @@
/* istanbul ignore file */
/**
* environment check to allow to use this package in a web context
*/
// By default, import the web code using a literal require, so that in webpack
// contexts, it will always be bundled
let mode = await import('./web.js');
// Then, if we're in a Node.js context, require the node version of this module
// using a variable, so that it will _not_ be included in a bundle, either
// during compilation or execution
if (typeof process !== 'undefined' && typeof process.release !== 'undefined' && process.release.name === 'node') {
const nodeMode = './node.js';
mode = await import(nodeMode);
}
// The net result will be that in a Node context, we'll have required both
// files but will use the correct one, and in the web context, we'll have only
// required the web file, thus ensuring that the Node file and related
// dependencies will not be bundled inadvertently.
export default mode.default;

View File

@@ -0,0 +1,14 @@
import log from 'loglevel';
interface LoggerInterface extends log.Logger {
progress(...msg: any[]): void;
}
declare function getLogger(name: string): LoggerInterface;
declare namespace getLogger {
var waitForBuffer: () => Promise<void>;
var setLevel: (name: string, level: log.LogLevelDesc) => void;
var clearLogger: () => void;
var setLogLevelsConfig: (logLevels?: Record<string, log.LogLevelDesc>, wdioLogLevel?: log.LogLevelDesc) => void;
}
export default getLogger;
export type Logger = LoggerInterface;
//# sourceMappingURL=node.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,UAAU,CAAA;AAsD1B,UAAU,eAAgB,SAAQ,GAAG,CAAC,MAAM;IACxC,QAAQ,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CACjC;AA+ED,iBAAwB,SAAS,CAAE,IAAI,EAAE,MAAM,mBAyB9C;kBAzBuB,SAAS;;;;;;eAAT,SAAS;AAiFjC,MAAM,MAAM,MAAM,GAAG,eAAe,CAAA"}

View File

@@ -0,0 +1,197 @@
import fs from 'node:fs';
import util from 'node:util';
import log from 'loglevel';
import chalk from 'chalk';
import prefix from 'loglevel-plugin-prefix';
import ansiStrip from 'strip-ansi';
prefix.reg(log);
const DEFAULT_LEVEL = process.env.WDIO_DEBUG
? 'trace'
: 'info';
const COLORS = {
error: 'red',
warn: 'yellow',
info: 'cyanBright',
debug: 'green',
trace: 'cyan',
progress: 'magenta'
};
const matches = {
COMMAND: 'COMMAND',
BIDICOMMAND: 'BIDI COMMAND',
DATA: 'DATA',
RESULT: 'RESULT',
BIDIRESULT: 'BIDI RESULT'
};
const SERIALIZERS = [{
/**
* display error stack
*/
matches: (err) => err instanceof Error,
serialize: (err) => err.stack
}, {
/**
* color commands blue
*/
matches: (log) => log === matches.COMMAND || log === matches.BIDICOMMAND,
serialize: (log) => chalk.magenta(log)
}, {
/**
* color data yellow
*/
matches: (log) => log === matches.DATA,
serialize: (log) => chalk.yellow(log)
}, {
/**
* color result cyan
*/
matches: (log) => log === matches.RESULT || log === matches.BIDIRESULT,
serialize: (log) => chalk.cyan(log)
}];
const loggers = log.getLoggers();
let logLevelsConfig = {};
const logCache = new Set();
let logFile;
const originalFactory = log.methodFactory;
const wdioLoggerMethodFactory = function (methodName, logLevel, loggerName) {
const rawMethod = originalFactory(methodName, logLevel, loggerName);
return (...args) => {
/**
* create logFile lazily
*/
if (!logFile && process.env.WDIO_LOG_PATH) {
logFile = fs.createWriteStream(process.env.WDIO_LOG_PATH);
}
/**
* split `prefixer: value` sting to `prefixer: ` and `value`
* so that SERIALIZERS can match certain string
*/
const match = Object.values(matches).filter(x => args[0].endsWith(`: ${x}`))[0];
if (match) {
const prefixStr = args.shift().slice(0, -match.length - 1);
args.unshift(prefixStr, match);
}
args = args.map((arg) => {
for (const s of SERIALIZERS) {
if (s.matches(arg)) {
return s.serialize(arg);
}
}
return arg;
});
const logText = ansiStrip(`${util.format.apply(this, args)}\n`);
if (logFile && logFile.writable) {
/**
* empty logging cache if stuff got logged before
*/
if (logCache.size) {
logCache.forEach((log) => {
if (logFile) {
logFile.write(log);
}
});
logCache.clear();
}
if (!logsContainInitPackageError(logText)) {
return logFile.write(logText);
}
// If we get Error during init of integration packages, write logs to both "outputDir" and the terminal
logFile.write(logText);
}
logCache.add(logText);
rawMethod(...args);
};
};
const progress = function (data) {
if (process.stdout.isTTY && this.getLevel() <= log.levels.INFO) {
const level = 'progress';
const timestampFormatter = chalk.gray(new Date().toISOString());
const levelFormatter = chalk[COLORS[level]](level.toUpperCase());
const nameFormatter = chalk.whiteBright(this.name);
const _data = data.length > 0 ? `${timestampFormatter} ${levelFormatter} ${nameFormatter}: ${data}` : '\r\x1b[K\x1b[?25h';
process.stdout.write('\u001B[?25l'); // Disable cursor in terminal
process.stdout.write(`${_data}\r`);
}
};
export default function getLogger(name) {
/**
* check if logger was already initiated
*/
if (loggers[name]) {
return loggers[name];
}
let logLevel = (process.env.WDIO_LOG_LEVEL || DEFAULT_LEVEL);
const logLevelName = getLogLevelName(name);
if (logLevelsConfig[logLevelName]) {
logLevel = logLevelsConfig[logLevelName];
}
loggers[name] = log.getLogger(name);
loggers[name].setLevel(logLevel);
loggers[name].methodFactory = wdioLoggerMethodFactory;
loggers[name].progress = progress;
prefix.apply(loggers[name], {
template: '%t %l %n:',
timestampFormatter: (date) => chalk.gray(date.toISOString()),
levelFormatter: (level) => chalk[COLORS[level]](level.toUpperCase()),
nameFormatter: (name) => chalk.whiteBright(name)
});
return loggers[name];
}
/**
* Wait for writable stream to be flushed.
* Calling this prevents part of the logs in the very env to be lost.
*/
getLogger.waitForBuffer = async () => new Promise(resolve => {
// @ts-ignore
if (logFile && Array.isArray(logFile.writableBuffer) && logFile.writableBuffer.length !== 0) {
return setTimeout(async () => {
await getLogger.waitForBuffer();
resolve();
}, 20);
}
resolve();
});
getLogger.setLevel = (name, level) => loggers[name].setLevel(level);
getLogger.clearLogger = () => {
if (logFile) {
logFile.end();
}
logFile = null;
};
getLogger.setLogLevelsConfig = (logLevels = {}, wdioLogLevel = DEFAULT_LEVEL) => {
/**
* set log level
*/
if (process.env.WDIO_LOG_LEVEL === undefined) {
process.env.WDIO_LOG_LEVEL = wdioLogLevel;
}
logLevelsConfig = {};
/**
* build logLevelsConfig object
*/
Object.entries(logLevels).forEach(([logName, logLevel]) => {
const logLevelName = getLogLevelName(logName);
logLevelsConfig[logLevelName] = logLevel;
});
/**
* set log level for each logger
*/
Object.keys(loggers).forEach(logName => {
const logLevelName = getLogLevelName(logName);
/**
* either apply log level from logLevels object or use global logLevel
*/
const logLevel = typeof logLevelsConfig[logLevelName] !== 'undefined' ? logLevelsConfig[logLevelName] : process.env.WDIO_LOG_LEVEL;
loggers[logName].setLevel(logLevel);
});
};
const getLogLevelName = (logName) => logName.split(':').shift();
function logsContainInitPackageError(logText) {
return ERROR_LOG_VALIDATOR.every(pattern => logText.includes(pattern));
}
const ERROR_LOG_VALIDATOR = [
'Couldn\'t find plugin',
'neither as wdio scoped package',
'nor as community package',
'Please make sure you have it installed'
];

View File

@@ -0,0 +1,9 @@
declare function getLogger(component: string): Console;
declare namespace getLogger {
var setLevel: () => void;
var setLogLevelsConfig: () => void;
var waitForBuffer: () => void;
var clearLogger: () => void;
}
export default getLogger;
//# sourceMappingURL=web.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAIA,iBAAwB,SAAS,CAAE,SAAS,EAAE,MAAM,WAcnD;kBAduB,SAAS;;;;;;eAAT,SAAS"}

View File

@@ -0,0 +1,21 @@
/* istanbul ignore file */
const LOG_METHODS = ['error', 'warn', 'info', 'debug', 'trace', 'silent'];
export default function getLogger(component) {
return LOG_METHODS.reduce((acc, cur) => {
const prop = cur;
// check if the method is available on console (web doesn't have
// 'silent', for example) before adding to acc
// eslint-disable-next-line no-console
if (console[prop]) {
// eslint-disable-next-line no-console
// @ts-ignore
acc[prop] = console[prop].bind(console, `${component}:`);
}
return acc;
}, {});
}
// logging interface expects a 'setLevel' method
getLogger.setLevel = () => { };
getLogger.setLogLevelsConfig = () => { };
getLogger.waitForBuffer = () => { };
getLogger.clearLogger = () => { };

View File

@@ -0,0 +1,41 @@
{
"name": "@wdio/logger",
"version": "8.38.0",
"description": "A helper utility for logging of WebdriverIO packages",
"author": "Christian Bromann <mail@bromann.dev>",
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-logger",
"license": "MIT",
"type": "module",
"types": "./build/index.d.ts",
"exports": {
".": "./build/index.js",
"./package.json": "./package.json"
},
"typeScriptVersion": "3.8.3",
"engines": {
"node": "^16.13 || >=18"
},
"repository": {
"type": "git",
"url": "git://github.com/webdriverio/webdriverio.git",
"directory": "packages/wdio-logger"
},
"keywords": [
"webdriver",
"wdio",
"wdio-utility"
],
"bugs": {
"url": "https://github.com/webdriverio/webdriverio/issues"
},
"dependencies": {
"chalk": "^5.1.2",
"loglevel": "^1.6.0",
"loglevel-plugin-prefix": "^0.8.4",
"strip-ansi": "^7.1.0"
},
"publishConfig": {
"access": "public"
},
"gitHead": "b8ebe679c772a858709164896c6b5ea86a42b146"
}