@rich-automation/lotto 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ exports.SELECTORS = {
10
10
  PURCHASE_TYPE_RANDOM_BTN: 'a[href="#divWay2Buy1"]#num2',
11
11
  PURCHASE_AMOUNT_SELECT: 'select#amoundApply',
12
12
  PURCHASE_AMOUNT_CONFIRM_BTN: 'input[value="확인"]#btnSelectNum',
13
- PURCHASE_BTN: 'input[value="구매하기"]#btnBuy',
13
+ PURCHASE_BTN: 'button#btnBuy',
14
14
  PURCHASE_CONFIRM_BTN: 'input[value="확인"][onclick="javascript:closepopupLayerConfirm(true);"]',
15
15
  PURCHASE_NUMBER_LIST: '#reportRow .nums'
16
16
  };
@@ -97,5 +97,10 @@ class PlaywrightPage {
97
97
  this.page.on(event, callback);
98
98
  return () => this.page.off(event, callback);
99
99
  }
100
+ waitForSelector(selector, timeout = 10000) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ yield this.page.waitForSelector(selector, { timeout });
103
+ });
104
+ }
100
105
  }
101
106
  exports.PlaywrightPage = PlaywrightPage;
@@ -101,5 +101,10 @@ class PuppeteerPage {
101
101
  this.page.on(event, callback);
102
102
  return () => this.page.off(event, callback);
103
103
  }
104
+ waitForSelector(selector, timeout = 10000) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ yield this.page.waitForSelector(selector, { timeout });
107
+ });
108
+ }
104
109
  }
105
110
  exports.PuppeteerPage = PuppeteerPage;
@@ -14,7 +14,8 @@ const LottoErrorCode = {
14
14
  INVALID_ROUND: 300001,
15
15
  INVALID_LOTTO_NUMBER: 300002,
16
16
  NOT_AUTHENTICATED: 300003,
17
- PURCHASE_UNAVAILABLE: 300004
17
+ PURCHASE_UNAVAILABLE: 300004,
18
+ PURCHASE_FAILED: 300005
18
19
  };
19
20
  const ErrorCode = Object.assign(Object.assign(Object.assign({}, BaseErrorCode), LoginErrorCode), LottoErrorCode);
20
21
  const ErrorName = (0, invertObject_1.invertObject)(ErrorCode);
@@ -27,6 +28,7 @@ const ErrorMessage = {
27
28
  [ErrorCode.INVALID_LOTTO_NUMBER]: '로또 번호가 올바르지 않습니다.',
28
29
  [ErrorCode.NOT_AUTHENTICATED]: '인증되지 않았습니다.',
29
30
  [ErrorCode.PURCHASE_UNAVAILABLE]: '현재는 로또 구매가 불가능합니다.',
31
+ [ErrorCode.PURCHASE_FAILED]: '로또 구매에 실패했습니다.',
30
32
  [ErrorCode.NOT_SUPPORTED]: '지원되지 않는 기능입니다.'
31
33
  };
32
34
  class LottoError extends Error {
@@ -54,6 +56,9 @@ class LottoError extends Error {
54
56
  static PurchaseUnavailable() {
55
57
  return new LottoError(ErrorCode.PURCHASE_UNAVAILABLE);
56
58
  }
59
+ static PurchaseFailed(message) {
60
+ return new LottoError(ErrorCode.PURCHASE_FAILED, message);
61
+ }
57
62
  static NotSupported(message) {
58
63
  return new LottoError(ErrorCode.NOT_SUPPORTED, message);
59
64
  }
@@ -128,12 +128,27 @@ class LottoService {
128
128
  yield page.click(selectors_1.SELECTORS.PURCHASE_BTN);
129
129
  this.logger.debug('[purchase]', 'click purchase confirm button');
130
130
  yield page.click(selectors_1.SELECTORS.PURCHASE_CONFIRM_BTN);
131
- yield page.wait(1000);
131
+ this.logger.debug('[purchase]', 'wait for purchase result');
132
+ try {
133
+ yield page.waitForSelector(selectors_1.SELECTORS.PURCHASE_NUMBER_LIST, 5000);
134
+ }
135
+ catch (e) {
136
+ this.logger.error('[purchase]', 'failed to wait for purchase result selector', selectors_1.SELECTORS.PURCHASE_NUMBER_LIST, e);
137
+ throw lottoError_1.default.PurchaseFailed('구매 결과 로딩 타임아웃');
138
+ }
132
139
  // game result
133
- this.logger.debug('[purchase]', 'print result');
134
- return page.querySelectorAll(selectors_1.SELECTORS.PURCHASE_NUMBER_LIST, elems => {
140
+ const result = yield page.querySelectorAll(selectors_1.SELECTORS.PURCHASE_NUMBER_LIST, elems => {
135
141
  return elems.map(it => Array.from(it.children).map(child => Number(child.innerHTML)));
136
142
  });
143
+ this.logger.debug('[purchase]', 'print result', result);
144
+ if (result.length === 0 || result.some(nums => nums.length === 0)) {
145
+ this.logger.error('[purchase]', 'failed to parse purchase result', {
146
+ selector: selectors_1.SELECTORS.PURCHASE_NUMBER_LIST,
147
+ result
148
+ });
149
+ throw lottoError_1.default.PurchaseFailed('구매 결과 파싱 실패');
150
+ }
151
+ return result;
137
152
  });
138
153
  this.check = (numbers, round = (0, getLastLottoRound_1.getLastLottoRound)()) => __awaiter(this, void 0, void 0, function* () {
139
154
  numbers.forEach(number => (0, validateLottoNumber_1.validateLottoNumber)(number));
@@ -7,7 +7,7 @@ export const SELECTORS = {
7
7
  PURCHASE_TYPE_RANDOM_BTN: 'a[href="#divWay2Buy1"]#num2',
8
8
  PURCHASE_AMOUNT_SELECT: 'select#amoundApply',
9
9
  PURCHASE_AMOUNT_CONFIRM_BTN: 'input[value="확인"]#btnSelectNum',
10
- PURCHASE_BTN: 'input[value="구매하기"]#btnBuy',
10
+ PURCHASE_BTN: 'button#btnBuy',
11
11
  PURCHASE_CONFIRM_BTN: 'input[value="확인"][onclick="javascript:closepopupLayerConfirm(true);"]',
12
12
  PURCHASE_NUMBER_LIST: '#reportRow .nums'
13
13
  };
@@ -94,4 +94,9 @@ export class PlaywrightPage {
94
94
  this.page.on(event, callback);
95
95
  return () => this.page.off(event, callback);
96
96
  }
97
+ waitForSelector(selector, timeout = 10000) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ yield this.page.waitForSelector(selector, { timeout });
100
+ });
101
+ }
97
102
  }
@@ -98,4 +98,9 @@ export class PuppeteerPage {
98
98
  this.page.on(event, callback);
99
99
  return () => this.page.off(event, callback);
100
100
  }
101
+ waitForSelector(selector, timeout = 10000) {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ yield this.page.waitForSelector(selector, { timeout });
104
+ });
105
+ }
101
106
  }
@@ -12,7 +12,8 @@ const LottoErrorCode = {
12
12
  INVALID_ROUND: 300001,
13
13
  INVALID_LOTTO_NUMBER: 300002,
14
14
  NOT_AUTHENTICATED: 300003,
15
- PURCHASE_UNAVAILABLE: 300004
15
+ PURCHASE_UNAVAILABLE: 300004,
16
+ PURCHASE_FAILED: 300005
16
17
  };
17
18
  const ErrorCode = Object.assign(Object.assign(Object.assign({}, BaseErrorCode), LoginErrorCode), LottoErrorCode);
18
19
  const ErrorName = invertObject(ErrorCode);
@@ -25,6 +26,7 @@ const ErrorMessage = {
25
26
  [ErrorCode.INVALID_LOTTO_NUMBER]: '로또 번호가 올바르지 않습니다.',
26
27
  [ErrorCode.NOT_AUTHENTICATED]: '인증되지 않았습니다.',
27
28
  [ErrorCode.PURCHASE_UNAVAILABLE]: '현재는 로또 구매가 불가능합니다.',
29
+ [ErrorCode.PURCHASE_FAILED]: '로또 구매에 실패했습니다.',
28
30
  [ErrorCode.NOT_SUPPORTED]: '지원되지 않는 기능입니다.'
29
31
  };
30
32
  export default class LottoError extends Error {
@@ -52,6 +54,9 @@ export default class LottoError extends Error {
52
54
  static PurchaseUnavailable() {
53
55
  return new LottoError(ErrorCode.PURCHASE_UNAVAILABLE);
54
56
  }
57
+ static PurchaseFailed(message) {
58
+ return new LottoError(ErrorCode.PURCHASE_FAILED, message);
59
+ }
55
60
  static NotSupported(message) {
56
61
  return new LottoError(ErrorCode.NOT_SUPPORTED, message);
57
62
  }
@@ -122,12 +122,27 @@ export class LottoService {
122
122
  yield page.click(SELECTORS.PURCHASE_BTN);
123
123
  this.logger.debug('[purchase]', 'click purchase confirm button');
124
124
  yield page.click(SELECTORS.PURCHASE_CONFIRM_BTN);
125
- yield page.wait(1000);
125
+ this.logger.debug('[purchase]', 'wait for purchase result');
126
+ try {
127
+ yield page.waitForSelector(SELECTORS.PURCHASE_NUMBER_LIST, 5000);
128
+ }
129
+ catch (e) {
130
+ this.logger.error('[purchase]', 'failed to wait for purchase result selector', SELECTORS.PURCHASE_NUMBER_LIST, e);
131
+ throw LottoError.PurchaseFailed('구매 결과 로딩 타임아웃');
132
+ }
126
133
  // game result
127
- this.logger.debug('[purchase]', 'print result');
128
- return page.querySelectorAll(SELECTORS.PURCHASE_NUMBER_LIST, elems => {
134
+ const result = yield page.querySelectorAll(SELECTORS.PURCHASE_NUMBER_LIST, elems => {
129
135
  return elems.map(it => Array.from(it.children).map(child => Number(child.innerHTML)));
130
136
  });
137
+ this.logger.debug('[purchase]', 'print result', result);
138
+ if (result.length === 0 || result.some(nums => nums.length === 0)) {
139
+ this.logger.error('[purchase]', 'failed to parse purchase result', {
140
+ selector: SELECTORS.PURCHASE_NUMBER_LIST,
141
+ result
142
+ });
143
+ throw LottoError.PurchaseFailed('구매 결과 파싱 실패');
144
+ }
145
+ return result;
131
146
  });
132
147
  this.check = (numbers, round = getLastLottoRound()) => __awaiter(this, void 0, void 0, function* () {
133
148
  numbers.forEach(number => validateLottoNumber(number));
@@ -18,4 +18,5 @@ export declare class PlaywrightPage implements BrowserPageInterface {
18
18
  setCookies(cookies: StringifiedCookies): Promise<void>;
19
19
  wait(param: 'idle' | 'load' | number): Promise<void>;
20
20
  on(event: BrowserPageEvents, callback: (...args: unknown[]) => void): () => Page;
21
+ waitForSelector(selector: string, timeout?: number): Promise<void>;
21
22
  }
@@ -16,4 +16,5 @@ export declare class PuppeteerPage implements BrowserPageInterface {
16
16
  setCookies(cookies: StringifiedCookies): Promise<void>;
17
17
  wait(param: 'idle' | 'load' | number): Promise<void>;
18
18
  on(event: BrowserPageEvents, callback: (...args: unknown[]) => void): () => Page;
19
+ waitForSelector(selector: string, timeout?: number): Promise<void>;
19
20
  }
@@ -3,6 +3,7 @@ declare const ErrorCode: {
3
3
  INVALID_LOTTO_NUMBER: 300002;
4
4
  NOT_AUTHENTICATED: 300003;
5
5
  PURCHASE_UNAVAILABLE: 300004;
6
+ PURCHASE_FAILED: 300005;
6
7
  CREDENTIALS_INCORRECT: 200001;
7
8
  INVALID_COOKIE: 200002;
8
9
  NETWORK_ERROR: 100001;
@@ -19,12 +20,14 @@ export default class LottoError extends Error {
19
20
  static InvalidLottoNumber(): LottoError;
20
21
  static NotAuthenticated(): LottoError;
21
22
  static PurchaseUnavailable(): LottoError;
23
+ static PurchaseFailed(message?: string): LottoError;
22
24
  static NotSupported(message?: string): LottoError;
23
25
  static get code(): {
24
26
  INVALID_ROUND: 300001;
25
27
  INVALID_LOTTO_NUMBER: 300002;
26
28
  NOT_AUTHENTICATED: 300003;
27
29
  PURCHASE_UNAVAILABLE: 300004;
30
+ PURCHASE_FAILED: 300005;
28
31
  CREDENTIALS_INCORRECT: 200001;
29
32
  INVALID_COOKIE: 200002;
30
33
  NETWORK_ERROR: 100001;
@@ -32,7 +35,7 @@ export default class LottoError extends Error {
32
35
  UNKNOWN_ERROR: 199999;
33
36
  };
34
37
  static getMessage(code: ErrorCodeNumber): string;
35
- static getName(code: ErrorCodeNumber): "INVALID_ROUND" | "INVALID_LOTTO_NUMBER" | "NOT_AUTHENTICATED" | "PURCHASE_UNAVAILABLE" | "CREDENTIALS_INCORRECT" | "INVALID_COOKIE" | "NETWORK_ERROR" | "NOT_SUPPORTED" | "UNKNOWN_ERROR";
38
+ static getName(code: ErrorCodeNumber): "INVALID_ROUND" | "INVALID_LOTTO_NUMBER" | "NOT_AUTHENTICATED" | "PURCHASE_UNAVAILABLE" | "PURCHASE_FAILED" | "CREDENTIALS_INCORRECT" | "INVALID_COOKIE" | "NETWORK_ERROR" | "NOT_SUPPORTED" | "UNKNOWN_ERROR";
36
39
  code: number;
37
40
  constructor(code: ErrorCodeNumber, message?: string);
38
41
  }
@@ -41,6 +41,7 @@ export interface BrowserPageInterface {
41
41
  wait(time: number): Promise<void>;
42
42
  wait(type: 'load'): Promise<void>;
43
43
  wait(type: 'idle'): Promise<void>;
44
+ waitForSelector(selector: string, timeout?: number): Promise<void>;
44
45
  getCookies(): Promise<StringifiedCookies>;
45
46
  setCookies(cookies: StringifiedCookies): Promise<void>;
46
47
  on(event: BrowserPageEvents, callback: (...args: any[]) => void): Unsubscribe;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rich-automation/lotto",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Lotto module",
5
5
  "publishConfig": {
6
6
  "access": "public",