From 89afffed99c4623291d40ee09f7f0d3038c8d4a5 Mon Sep 17 00:00:00 2001 From: kkb912002 Date: Fri, 25 Apr 2025 08:51:59 +0900 Subject: [PATCH 1/3] support log commands --- lib/commands/log.ts | 39 +++++++++++++++++++++++++++++++++++++++ lib/driver.js | 7 +++++++ 2 files changed, 46 insertions(+) create mode 100644 lib/commands/log.ts diff --git a/lib/commands/log.ts b/lib/commands/log.ts new file mode 100644 index 00000000..0a473306 --- /dev/null +++ b/lib/commands/log.ts @@ -0,0 +1,39 @@ +import _ from 'lodash'; +import { WindowsDriver } from '../driver'; +import { LogDefRecord, StringRecord } from '@appium/types'; + +const COLOR_CODE_PATTERN = /\u001b\[(\d+(;\d+)*)?m/g; // eslint-disable-line no-control-regex +const GET_SERVER_LOGS_FEATURE = 'get_server_logs'; +const DEFAULT_LOG_LEVEL = 'ALL'; + +export const supportedLogTypes: LogDefRecord = { + server: { + description: 'Appium server logs', + getter: (self: WindowsDriver): LogEntry[] => { + self.assertFeatureEnabled(GET_SERVER_LOGS_FEATURE); + return self.log.unwrap().record.map(nativeLogEntryToSeleniumEntry); + }, + }, +}; + +function nativeLogEntryToSeleniumEntry(x: StringRecord): LogEntry { + const msg = _.isEmpty(x.prefix) ? x.message : `[${x.prefix}] ${x.message}`; + return toLogEntry( + _.replace(msg, COLOR_CODE_PATTERN, ''), + x.timestamp ?? Date.now() + ); +} + +function toLogEntry( + message: string, + timestamp: number, + level: string = DEFAULT_LOG_LEVEL +): LogEntry { + return { timestamp, level, message }; +} + +interface LogEntry { + timestamp: number; + level: string; + message: string; +} diff --git a/lib/driver.js b/lib/driver.js index fdfed07a..d5c017ec 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -14,6 +14,7 @@ import * as powershellCommands from './commands/powershell'; import * as recordScreenCommands from './commands/record-screen'; import * as touchCommands from './commands/touch'; import * as contextCommands from './commands/context'; +import * as logCommands from './commands/log'; import { POWER_SHELL_FEATURE } from './constants'; import { newMethodMap } from './method-map'; import { executeMethodMap } from './execute-method-map'; @@ -32,6 +33,10 @@ const NO_PROXY = [ ['GET', new RegExp('^/session/[^/]+/screenshot')], ['GET', new RegExp('^/session/[^/]+/contexts?')], ['POST', new RegExp('^/session/[^/]+/context')], + ['GET', new RegExp('^/session/[^/]+/log/types')], + ['POST', new RegExp('^/session/[^/]+/log')], + ['GET', new RegExp('^/session/[^/]+/se/log/types')], + ['POST', new RegExp('^/session/[^/]+/se/log')], // Workarounds for // - https://github.com/appium/appium/issues/15923 // - https://github.com/appium/appium/issues/16316 @@ -219,6 +224,8 @@ export class WindowsDriver extends BaseDriver { getContexts = contextCommands.getContexts; getCurrentContext = contextCommands.getCurrentContext; setContext = contextCommands.setContext; + + supportedLogTypes = logCommands.supportedLogTypes; } export default WindowsDriver; From 6c3a8805c51875ca1cfb0bf452dfa42c148e90e9 Mon Sep 17 00:00:00 2001 From: kkb912002 Date: Fri, 25 Apr 2025 08:53:24 +0900 Subject: [PATCH 2/3] add test for log commands --- test/e2e/commands/log-e2e-specs.js | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/e2e/commands/log-e2e-specs.js diff --git a/test/e2e/commands/log-e2e-specs.js b/test/e2e/commands/log-e2e-specs.js new file mode 100644 index 00000000..ecb61cf3 --- /dev/null +++ b/test/e2e/commands/log-e2e-specs.js @@ -0,0 +1,40 @@ +import { buildWdIoOptions } from '../helpers'; +import { remote as wdio } from 'webdriverio'; + +describe('log', function () { + let chai; + /** @type {import('webdriverio').Browser} */ + let driver; + + before(async function () { + chai = await import('chai'); + const chaiAsPromised = await import('chai-as-promised'); + + chai.should(); + chai.use(chaiAsPromised.default); + + driver = await wdio(buildWdIoOptions('Root')); + }); + + after(async function () { + try { + if (driver) { + await driver.deleteSession(); + } + } finally { + driver = null; + } + }); + + it('should get the list of available logs', async function () { + (await driver.getLogTypes()).should.eql(['server']); + }); + + it('should throw an error when an invalid type is given', async function () { + await driver.getLogs('INVALID_LOG_TYPE').should.rejected; + }); + + it('should get server logs', async function () { + (await driver.getLogs('server')).should.be.an('array'); + }); +}); From 1496fa052d84ba51865e000e9be4868a12828665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B8=B0=EB=B2=94=28Kim=2C=20Gi-Beom=29?= Date: Fri, 25 Apr 2025 16:30:34 +0900 Subject: [PATCH 3/3] apply review(use import type, should.be.rejected) --- lib/commands/log.ts | 2 +- test/e2e/commands/log-e2e-specs.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commands/log.ts b/lib/commands/log.ts index 0a473306..fa469f35 100644 --- a/lib/commands/log.ts +++ b/lib/commands/log.ts @@ -1,5 +1,5 @@ import _ from 'lodash'; -import { WindowsDriver } from '../driver'; +import type { WindowsDriver } from '../driver'; import { LogDefRecord, StringRecord } from '@appium/types'; const COLOR_CODE_PATTERN = /\u001b\[(\d+(;\d+)*)?m/g; // eslint-disable-line no-control-regex diff --git a/test/e2e/commands/log-e2e-specs.js b/test/e2e/commands/log-e2e-specs.js index ecb61cf3..350856a6 100644 --- a/test/e2e/commands/log-e2e-specs.js +++ b/test/e2e/commands/log-e2e-specs.js @@ -31,7 +31,7 @@ describe('log', function () { }); it('should throw an error when an invalid type is given', async function () { - await driver.getLogs('INVALID_LOG_TYPE').should.rejected; + await driver.getLogs('INVALID_LOG_TYPE').should.be.rejected; }); it('should get server logs', async function () {