在量角器 7 中使用异步等待的短堆栈跟踪
Short stack trace with async await in protractor 7
我正在尝试使用量角器和茉莉花自动执行一些测试,并且我正在使用 async/await 来解决承诺。
问题是,当确实发生错误时,堆栈跟踪太短,因此我似乎无法找到问题的根源。
我确保在配置文件中将 SELENIUM_PROMISE_MANAGER 设置为 FALSE。
我正在使用量角器 7 和节点 14.16.0
有谁知道如何解决这个问题?没有足够的细节
这是一个代码片段
const invoicesButton: Button = new Button("Invoices", LocatorType.Href, "#/Invoices");
describe("Kouka test", function () {
beforeEach(function () {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000000;
});
it("Does a random test", async function () {
await browser.get("https://appdev.expensya.com/Portal/#/Login?lang=en");
await loginEmailInput.typeText("amr.refacto@yopmail.com")
await loginPasswordInput.typeText("a")
await loginButton.click(true);
await dashboardPage.invoicesButton.click().catch((e) => {
e.stackTraceLimit = Infinity;
throw e;
});
await userInvoicesPage.createManualInvoice(invoice).catch((e) => {
e.stackTraceLimit = Infinity;
console.error("TEST ERROR ", e);
throw e;
});
await browser.sleep(10000);
});
});
这里是“按钮”的定义Class:
import { browser } from "protractor";
import { WebComponent } from "./webComponent";
export class Button extends WebComponent {
/**
* @param webElementText Text that the web element contains.
* @param locatorType Locator type of the web element to search for.
* @param locator Locator of the web element to search for.
* @param parentElement Parent Web Component if it exists.
*/
constructor(webElementText, locatorType, locator, parentElement: WebComponent = null) {
super(webElementText, locatorType, locator, parentElement);
}
async click(usingJavaScript = false) {
if (usingJavaScript) {
await this.isPresent();
await browser.executeScript("arguments[0].click();", await this.webElement)
}
else {
await this.isVisible();
await this.isClickable();
await this.webElement.click();
}
}
}
最后,这是堆栈跟踪
Started
Jasmine started
undefined
F
Kouka test
× Does a random test
- Failed: Wait timed out after 10012ms
at C:\Users\Amrou Bellalouna\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2201:17
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
From asynchronous test:
Error
at Suite.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:20:5)
at Object.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:15:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
Failures:
1) Kouka test Does a random test
Message:
Failed: Wait timed out after 10012ms
Stack:
TimeoutError: Wait timed out after 10012ms
at C:\Users\Amrou Bellalouna\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2201:17
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
From asynchronous test:
Error
at Suite.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:20:5)
at Object.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:15:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
1 spec, 1 failure
Finished in 19.461 seconds
我记得不久前试图解决这个问题,但我做不到。但我实施了一系列变通办法,显然这就足够了
首先,你能分享一下他们在做什么吗
await this.isPresent();
await this.isVisible();
await this.isClickable();
- 有这个功能
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime
)
}
您可以按照 here 所述使用 browser.wait
的第三个参数的优势,并在失败时包含一条可选消息,如下所示
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime,
`Element ${this.webElement.locator().toString()} is not present after ${this._elapsedTime}ms`);
)
}
- (我给你我所有的秘制酱料哈哈)如果你把它添加到配置
onPrepare
中
/**
* Set global environment configuration
*/
Object.defineProperty(global, '__stack', {
get: function() {
let orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack) {
return stack;
};
let err = new Error();
Error.captureStackTrace(err, arguments.callee);
let stack = err.stack;
Error.prepareStackTrace = orig;
return stack;
},
});
// returns name of the file from which is called
Object.defineProperty(global, '__file', {
get: function() {
let path = __stack[1].getFileName();
try {
//*nix OSes
return path.match(/[^\/]+\/[^\/]+$/)[0];
} catch (error) {
//Windows based OSes
return path.match(/[^\]+\[^\]+$/)[0];
}
},
});
// returns function name from which is called
Object.defineProperty(global, '__function', {
get: function() {
return __stack[1].getFunctionName();
},
});
// returns line number of the position in code when called
Object.defineProperty(global, '__line', {
get: function() {
return __stack[1].getLineNumber();
},
});
然后你可以用它来记录文件名、函数名和调用它的行
例如,
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime,
`Failed at ${__file} -> ${__function}() -> line ${__line}`
)
}
会导致这个错误
- Failed: Failed at common/index.js -> isVisible() -> line 82
Wait timed out after 1032ms
Wait timed out after 1032ms
因此您可以根据自己的需要调整此设置
我也刚刚意识到你可能想要玩弄 __stack
变量本身
我正在尝试使用量角器和茉莉花自动执行一些测试,并且我正在使用 async/await 来解决承诺。
问题是,当确实发生错误时,堆栈跟踪太短,因此我似乎无法找到问题的根源。
我确保在配置文件中将 SELENIUM_PROMISE_MANAGER 设置为 FALSE。
我正在使用量角器 7 和节点 14.16.0
有谁知道如何解决这个问题?没有足够的细节
这是一个代码片段
const invoicesButton: Button = new Button("Invoices", LocatorType.Href, "#/Invoices");
describe("Kouka test", function () {
beforeEach(function () {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000000;
});
it("Does a random test", async function () {
await browser.get("https://appdev.expensya.com/Portal/#/Login?lang=en");
await loginEmailInput.typeText("amr.refacto@yopmail.com")
await loginPasswordInput.typeText("a")
await loginButton.click(true);
await dashboardPage.invoicesButton.click().catch((e) => {
e.stackTraceLimit = Infinity;
throw e;
});
await userInvoicesPage.createManualInvoice(invoice).catch((e) => {
e.stackTraceLimit = Infinity;
console.error("TEST ERROR ", e);
throw e;
});
await browser.sleep(10000);
});
});
这里是“按钮”的定义Class:
import { browser } from "protractor";
import { WebComponent } from "./webComponent";
export class Button extends WebComponent {
/**
* @param webElementText Text that the web element contains.
* @param locatorType Locator type of the web element to search for.
* @param locator Locator of the web element to search for.
* @param parentElement Parent Web Component if it exists.
*/
constructor(webElementText, locatorType, locator, parentElement: WebComponent = null) {
super(webElementText, locatorType, locator, parentElement);
}
async click(usingJavaScript = false) {
if (usingJavaScript) {
await this.isPresent();
await browser.executeScript("arguments[0].click();", await this.webElement)
}
else {
await this.isVisible();
await this.isClickable();
await this.webElement.click();
}
}
}
最后,这是堆栈跟踪
Started
Jasmine started
undefined
F
Kouka test
× Does a random test
- Failed: Wait timed out after 10012ms
at C:\Users\Amrou Bellalouna\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2201:17
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
From asynchronous test:
Error
at Suite.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:20:5)
at Object.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:15:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
Failures:
1) Kouka test Does a random test
Message:
Failed: Wait timed out after 10012ms
Stack:
TimeoutError: Wait timed out after 10012ms
at C:\Users\Amrou Bellalouna\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2201:17
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
From asynchronous test:
Error
at Suite.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:20:5)
at Object.<anonymous> (C:\Users\Amrou Bellalouna\source\repos\NewE2EArchitecture\NewArchitecture\koukouTest.spec.ts:15:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
1 spec, 1 failure
Finished in 19.461 seconds
我记得不久前试图解决这个问题,但我做不到。但我实施了一系列变通办法,显然这就足够了
首先,你能分享一下他们在做什么吗
await this.isPresent();
await this.isVisible();
await this.isClickable();
- 有这个功能
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime
)
}
您可以按照 here 所述使用 browser.wait
的第三个参数的优势,并在失败时包含一条可选消息,如下所示
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime,
`Element ${this.webElement.locator().toString()} is not present after ${this._elapsedTime}ms`);
)
}
- (我给你我所有的秘制酱料哈哈)如果你把它添加到配置
onPrepare
中
/**
* Set global environment configuration
*/
Object.defineProperty(global, '__stack', {
get: function() {
let orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack) {
return stack;
};
let err = new Error();
Error.captureStackTrace(err, arguments.callee);
let stack = err.stack;
Error.prepareStackTrace = orig;
return stack;
},
});
// returns name of the file from which is called
Object.defineProperty(global, '__file', {
get: function() {
let path = __stack[1].getFileName();
try {
//*nix OSes
return path.match(/[^\/]+\/[^\/]+$/)[0];
} catch (error) {
//Windows based OSes
return path.match(/[^\]+\[^\]+$/)[0];
}
},
});
// returns function name from which is called
Object.defineProperty(global, '__function', {
get: function() {
return __stack[1].getFunctionName();
},
});
// returns line number of the position in code when called
Object.defineProperty(global, '__line', {
get: function() {
return __stack[1].getLineNumber();
},
});
然后你可以用它来记录文件名、函数名和调用它的行
例如,
async isVisible(){
await browser.wait(
ExpectedConditions.visibilityOf(this.webElement),
this._elapsedTime,
`Failed at ${__file} -> ${__function}() -> line ${__line}`
)
}
会导致这个错误
- Failed: Failed at common/index.js -> isVisible() -> line 82
Wait timed out after 1032ms
Wait timed out after 1032ms
因此您可以根据自己的需要调整此设置
我也刚刚意识到你可能想要玩弄 __stack
变量本身