Protractor: ExpectedConditions ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด elementNotToBeCovered ๊ตฌํ˜„

์— ๋งŒ๋“  2015๋…„ 07์›” 07์ผ  ยท  48์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: angular/protractor

PRs plz! easy untriaged user experience feature request

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

+1

๋ชจ๋“  48 ๋Œ“๊ธ€

์ •๋ง ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค

์ด๊ฒƒ์€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๋กœ๋” ๋ฐ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” globaleaks์—์„œ ์ •ํ™•ํžˆ ์šฐ๋ฆฌ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

+1

ํŽ˜์ด์ง€ ์ƒ๋‹จ์— ํ‘œ์‹œ๋˜๋Š” ํŒ์—… ๋ฐ ์˜ค๋ฒ„๋ ˆ์ด์— ์ด๊ฒƒ์ด ์ •๋ง ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ExpectedConditions.elementToBeClickable์ด ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค...

๊ทธ๋ž˜ ์ด๊ฑฐ! ๋‚˜๋Š” ์ง€์†์ ์œผ๋กœ _"์š”์†Œ๊ฐ€ (x,y) ์ง€์ ์—์„œ ํด๋ฆญํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์š”์†Œ๋Š” ํด๋ฆญ์„ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค:"_ ์Šคํฌ๋กคํ•˜๊ณ  ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ํ›„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ~14%์˜ ์‹œ๊ฐ„๋งŒ .. ๋ถˆ๋งŒ์Šค๋Ÿฌ์šด. elementVisible ๋˜๋Š” elementToBeClickable์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์กฐ์ฐจ ํ•ญ์ƒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

+1

+1

+1

์ด ๊ธฐ๋Šฅ์ด ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ์ถœ์‹œ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ๋„ˆ๋ฌด ์งœ์ฆ๋‚ฉ๋‹ˆ๋‹ค. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

+1

+1

+1

+1

@sjelin ๋‹น์‹ ์€ ์ด๊ฒƒ์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ ํ–ˆ์Šต๋‹ˆ๊นŒ?

We would address this using document.elementFromPoint and element.getBoundingClientRect pretty easily actually. elementFromPoint isn't totally standard at this point, though it appears to be supported by all browsers. The consistency issue is real though. Donno if we should leave this the way it is or "fix" it

+1000000000

+999

+2000000

+2000000

+999

+1

+1

+1

+1
ํŽธ์ง‘: ๊ทธ๋Ÿผ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” +1 ๋ฌธ์ œ์— ๋Œ€ํ•ด ํˆฌํ‘œํ•˜๋Š” ๊ฒƒ์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ๊ฝค ์ผ๋ฐ˜์ ์ธ ๊ด€ํ–‰์ž„์„ ๋ณด์•˜๊ณ  ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ๊ฐ๋„๊ธฐ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŽ์ด ์ž‘์„ฑํ•˜๋ฉด์„œ ์‹คํ–‰ํ•œ ๋ฌธ์ œ์ด๋ฏ€๋กœ ๊ตฌํ˜„๋˜๋Š” ๊ฒƒ์„ ๋ณด๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๋ฏธ๋ž˜๋ฅผ ์œ„ํ•ด ๊ธฐ์–ตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด PR์„ +{์ˆซ์ž}๋ฒˆ ์ค‘์ง€ํ•˜์„ธ์š”. ์ด๊ฒƒ์€ ๋„์›€์ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ...

์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์†Œ๋ฅผ ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กคํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ๋ชจ๋‹ฌ ๋“ฑ๊ณผ ๊ฐ™์€ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

var el = $('.myElement');
browser.executeScript('arguments[0].scrollIntoView()', el.getWebElement());

ํ˜„์žฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ํด๋ฆญํ•˜๋ ค๋Š” ์š”์†Œ๋ฅผ "์ฐจ๋‹จ"ํ•˜๋Š” ์š”์†Œ( id="spinner" )๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฐจ๋‹จ ์š”์†Œ๊ฐ€ ๋ณด์ด์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
broswer.wait(EC.invisibilityOf($(โ€˜#spinnerโ€™)), 5000)

EC.invisibilityOf ๋กœ๋Š” ํ•ญ์ƒ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ๊ฐ๋„๊ธฐ๋Š” ์š”์†Œ๊ฐ€ ๋ณด์ด์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๋‹ค๋ฅธ ์š”์†Œ์— ์˜ํ•ด ๋ฎ์—ฌ ์žˆ๋‹ค๊ณ  ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚ด ํ…Œ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜์—์„œ ๋งํฌ๊ฐ€ ์ƒ์œ„ div์— ํฌํ•จ๋œ ๊ฒƒ์œผ๋กœ ๋ณด๊ณ ๋˜๊ณ  invisibilityOf ๋Š” ์˜์›ํžˆ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. toNotBeCoveredBy ๋Œ€ํ•œ ์—ด๋ง

์ด ๋ฌธ์ œ๋Š” 2๋…„ ์ „์ž…๋‹ˆ๋‹ค. ์ฐพ์„ ์ˆ˜ ์—†๊ณ  ์—ฌ์ „ํžˆ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ์ƒํ™ฉ์—์„œ๋Š” ์š”์†Œ๊ฐ€ ๋ณด์ด์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฎ๋Š” ์š”์†Œ๊ฐ€ ์–ด๋–ค ์‹œ์ ์—์„œ๋„ ๋ณด์ด์ง€ ์•Š๊ณ  ์‹œ๊ฐ์ ์œผ๋กœ ์š”์†Œ๋ฅผ ๋ฎ๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ์š”์†Œ๊ฐ€ ํด๋ฆญ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

"toNotBeCoveredBy"์— ๋Œ€ํ•ด +1

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

"use strict";

function elementWithAttributeHasNotValue(htmlElement, attribute, value) {
    return htmlElement.getAttribute(attribute).then((elementAttribute) => {
        return !elementAttribute.includes(value);
    });
}

class Helper {
    waitForAngularInRoomAnimationToBeDone() {
        const inRoomElement = element(by.className("in-room"));

        browser.wait(elementWithAttributeHasNotValue(inRoomElement, "class", "ng-animate"), browser.params.DEFAULT_TIMEOUT_MS);
    }
}

module.exports = Helper;

๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„๊ณผ ์ƒ์ˆ˜์˜ ์ด๋ฆ„์€ ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ๋‹ค๋ฅด์ง€๋งŒ ๋‚˜๋จธ์ง€๋Š” ๋” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด ํ…Œ์ŠคํŠธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

helper.waitForAngularInRoomAnimationToBeDone();

๋ฌธ์ œ๋Š” ๋‚ด ์ƒํ™ฉ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ˆœ๊ฐ„์˜ ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ์ƒํƒœ๋ฅผ ์บก์ฒ˜ํ•˜๋Š” ์˜ค๋ฅ˜์˜ ์Šคํฌ๋ฆฐ ์ƒท์„ ๋ณผ ๋•Œ ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ๋ณด์ด๊ณ  ํด๋ฆญํ•˜๋ ค๋Š” ์š”์†Œ๊ฐ€ ๋ณด์ด์ง€๋งŒ ๊ฐ๋„๊ธฐ๋Š” ๋‹ค๋ฅธ ์š”์†Œ๊ฐ€ ํด๋ฆญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ์š”์†Œ๊ฐ€ ํ‘œ์‹œ๋˜๊ฑฐ๋‚˜ ํ™œ์„ฑํ™”๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์€ ์š”์†Œ๊ฐ€ ์ด๋ฏธ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๊ณ  ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ์š”์†Œ๋ฅผ ํด๋ฆญํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. Chrome์— ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉฐ ๋งค๋ฒˆ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ 20% ์ •๋„๋งŒ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@MihailSeykov ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋๋‚  ๋•Œ ์Šคํฌ๋ฆฐ์ƒท์ด EC.and ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์š”์†Œ๋ฅผ ๋ฎ๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๋Š” invisibilityOf ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋•Œ๋กœ๋Š” ์š”์†Œ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋˜์ง€๋งŒ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ›„ ๋‹ค๋ฅธ ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๋“ค์ด ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์— ์Ÿ๋Š” ๋ชจ๋“  ๋…ธ๊ณ ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค(๊ฐ€๋Šฅํ•œ ํ•œ ๋…ธ๋ ฅํ•˜๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค).

ํ•˜์ง€๋งŒ... ์™œ ์ด๊ฒƒ์ด ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ธฐ๋ณธ/์ฐจ๋‹จ/๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•ญ๋ชฉ์ด dom์—์„œ ์ˆจ๊ฒจ์ง€๊ฑฐ๋‚˜ ํ‘œ์‹œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ž ์ž๊ธฐ ์—†์ด๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ณด์ด์ง€ ์•Š๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ๊ฐ€์‹œ์„ฑ์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ์—ฌ๋Ÿฌ ์กฐํ•ฉ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ hacky hacky hack hacks๊ฐ€ ์•„๋‹Œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์™œ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ์ด ๊ฐ€์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š์€์ง€ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2๋…„์ด ๋„˜์—ˆ๋Š”๋ฐ ์•„์ง๋„ ๊ณ ์ณ์ง€์ง€๊ฐ€ ์•Š๋„ค์š”??!! ํ•ดํ‚น์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ์ˆ˜์ •ํ•˜์„ธ์š”!

๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? :)
๋‚˜๋Š” ๋งˆ์นจ๋‚ด ๋‚ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์น˜๋ฃŒ๋ฒ•์„ ์ฐพ์•˜์ง€๋งŒ

์ด์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ทธ๊ฒƒ์„๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๊ฒฐ์ฝ” ๊ณ ์น  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ๊ทธ๊ฒƒ์€ ๋กœ๋“œ๋งต์— ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์œผ๋ ค๋ฉด ์‹ค์ œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ณณ์„ "์ฆ๋ช…"ํ•  ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ์™€ ์˜ˆ์ œ ๊ฐ๋„๊ธฐ ์ฝ”๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋˜ํ•œ ์š”์†Œ๋กœ ์Šคํฌ๋กคํ•˜๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฃผ์„์—์„œ ๋งŽ์€ ๊ฒƒ์„ ์ฝ๊ณ  ์žˆ์œผ๋ฉฐ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์—ฌ์ „ํžˆ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์Šคํฌ๋กค ์ž์ฒด์—๋„ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค๋Š” ์‚ฌ์‹ค๊ณผ ๊ด€๋ จ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋Š” ๋งค์šฐ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ˆ„๊ฐ€ ์šฐ๋ฆฌ์—๊ฒŒ ๊ทธ๊ฒƒ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ €๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ ์—ญ์‹œ ์ œ๊ฐ€ Selenium์— ๋Œ€ํ•ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐ ๋“ฑ์„ ๊ตฌ์ถ•ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์„ฑ๊ฐ€์‹  ์ผ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ž‘์€ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฐฉ๋ฒ•์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด ์š”์†Œ๋ฅผ ์ฆ‰์‹œ ํด๋ฆญํ•œ๋‹ค๋Š” ์ ์„ ๋ช…์‹ฌํ•˜์‹ญ์‹œ์˜ค.

import { ElementFinder, promise } from 'protractor';
export let testHelpers = {
  isClickable(el: ElementFinder): promise.Promise<boolean> {
    return new promise.Promise(resolve => {
      let interval = setInterval(() => {
        el.click().then(() => {
          clearInterval(interval);
          setTimeout(() => {
            resolve(true);
          }, 500);
        }, () => { });
      }, 100);
    });
  }
}

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ:

import { testHelpers } from '../src/core/e2e/helpers';
describe('App', () => {
  it('should do something', () {
    let btn = $('.cls');
    browser.wait(testHelpers.isClickable(btn), 3000);
  });
});

๋‚ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๊ธฐ ์ „์— ํด๋ฆญํ•˜๋ ค๋Š” ์š”์†Œ๋ฅผ ๋ฎ๊ณ  ์žˆ๋Š” ์š”์†Œ๋ฅผ DOM์—์„œ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
await browser.executeScript("arguments[0].remove();", coverElement);

๊ฑฐ์˜ 3๋…„์ด ์ง€๋‚ฌ์Šต๋‹ˆ๋‹ค... ์š”์ฒญํ•œ ๊ธฐ๋Šฅ์ด _๊ฐ๋„๊ธฐ_ ๋‚ด์—์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?
์š”์†Œ ํด๋ฆญ ๊ฐ€๋Šฅ์„ฑ์„ ์ฐจ๋‹จํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์ „์ฒด์— sleep ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@nmfernandes ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์กฐ๊ธˆ ๋œ ๊ทน์  ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ arguments[0].style.visibility='hidden'; ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์–ด์จŒ๋“  ๋‹น์‹ ์˜ ์•„์ด๋””์–ด๋Š” ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ฑฐ์˜ 4๋…„์ด ์ง€๋‚ฌ๋Š”๋ฐ, ์ด๊ฑฐ ์ฃผ์„ธ์š”? ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ƒํ˜ธ ์ž‘์šฉ ์‚ฌ์ด์— ์งง์€ ์ ˆ์ „ ๋ชจ๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, sleeps ๋Š” ๋‚ด๊ฐ€(๊ทธ๋ฆฌ๊ณ  ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋˜ํ•œ) ํ”ผํ•˜๊ณ  ์‹ถ์€ ๋งŽ์€ ์‹œ๊ฐ„์„ ์ถ•์ ํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ๋“ ์ง€ ์ด ๋ฌธ์ œ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๋ณต์ œ ๋ฐ ์‹คํ–‰๋งŒ ํ•˜๋„๋ก github ์ €์žฅ์†Œ๋ฅผ ์ „๋‹ฌํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๊ฐ๋„๊ธฐ ํŒ€์ด ์ด์— ๋Œ€ํ•ด ๋ฌด์—‡์ด๋“  ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋งค์šฐ ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ๊ทธ๊ฒƒ์€ Selenium ๋˜๋Š” Chromedriver์˜ ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

  • 1

๋” ์ด์ƒ Google์—์„œ ์ผํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ• ๋‹น ์ทจ์†Œ

async / await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 1๊ฐœ ๋˜๋Š” 2๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋„์šฐ๋ฏธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. elem ๋ฐ
retryCount . 0.5์ดˆ๋งˆ๋‹ค ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด retryCount๊ฐ€ ๋‹ค ๋–จ์–ด์ง€๊ฑฐ๋‚˜ ๋ฒ„ํŠผ์ด ํด๋ฆญ๋  ๋•Œ๊นŒ์ง€ ๋‹ค์‹œ ํด๋ฆญ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

export const clickOnElementWithRetry = async (elem: ElementFinder, retryCount: number = 5) => {

    while (retryCount) {
        try {
            await elem.click();
            retryCount = 0;
        }
        catch (e) {
            if(retryCount === 0)
                throw "Couldn't click element";
            await browser.sleep(500);
            retryCount--;   
        }
    }

}

์‚ฌ์–‘ ํŒŒ์ผ ๋˜๋Š” ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ชจ๋“  ์œ„์น˜์—์„œ:

import { clickOnElementWithRetry } from './helpers/';
it('Clicks on some element', async () => {

    const someButton = element(by.id("someElementId"));
    clickOnElementWithRetry(someButton)
})
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰