-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.ts
132 lines (107 loc) · 4.08 KB
/
script.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require('dotenv').config()
const { remote } = require('webdriverio');
const LOGIN_URL = 'https://cloud.qingchengfit.cn/mobile/users/access/?next_url=https%3A//yun.qingchengfit.cn/shop/48560/welcome#/login';
const COURSES_URL = 'https://yun.qingchengfit.cn/shop/48560/m/user/schedules/group/?auto=1';
const TODAY_MID_NIGHT = new Date().toLocaleDateString();
const TODAY_MID_NIGHT_MILI = new Date(TODAY_MID_NIGHT).getTime()
const MILI_1300 = 1000 * 60 * 60 * 11;
const MILI_1830 = 1000 * 60 * 60 * 18.5;
const MILI_2000 = 1000 * 60 * 60 * 20;
const CLASS_MAP = {
1300: {
string: '13:00 - ',
mili: TODAY_MID_NIGHT_MILI + MILI_1300
},
1830: {
string: '18:30 - ',
mili: TODAY_MID_NIGHT_MILI + MILI_1830
},
2000: {
string: '20:00 - ',
mili: TODAY_MID_NIGHT_MILI + MILI_2000
}
};
const [, , ...args] = process.argv;
const classStartTime = args[0]
const phoneNumber = args[1] || process.env.PHONE
const password = args[2] || process.env.PASSWORD
const TARGET = CLASS_MAP[classStartTime];
if (!phoneNumber || !password || !TARGET) {
console.error('wrong args')
process.exit(1)
}
(async () => {
const browser = await remote({
capabilities: {
browserName: 'chrome',
// "goog:chromeOptions": {
// mobileEmulation: {'deviceName': 'iPhone 11'},
// args: [ '--no-sandbox',
// '--disable-gpu',
// '--disable-notifications',
// '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
// ]
// }
},
});
// browser.setWindowSize(411, 823);
await browser.url(LOGIN_URL);
// login
const switchToPasswordBtn = await browser.$('.txt-cell.text-center a.s-txt-live')
await switchToPasswordBtn.click()
const phoneNumInput = await browser.$('input[placeholder="请输入手机号码"]')
await phoneNumInput.setValue(phoneNumber)
const passwordInput = await browser.$('input[placeholder="请输入登录密码"]')
await passwordInput.setValue(password)
const agreementCheckBox = await browser.$('.checkbox')
await agreementCheckBox.click()
const loginBtn = await browser.$('button.u-btn-primary')
await loginBtn.click();
// go to tomorrow's class list
await browser.pause(1000)
const toBookBtn = await browser.$('span=约')
await toBookBtn.click();
await browser.pause(1000)
const tomorrow = await browser.$(function () {
const today = document.querySelector(".date.z-active.z-today")
return today.parentElement.nextElementSibling.firstElementChild
})
await tomorrow.click()
await browser.pause(1000)
const classListLoading = await browser.$('p=数据加载中...')
await classListLoading.waitForDisplayed({ reverse: true, timeout: 5000, timeoutMsg: 'class list should finish loading in 5 sec' });
// go to class page
// wait till class is bookable
await browser.waitUntil(function() {
const now = new Date().getTime()
// return now > TARGET.mili
// return now > TODAY_MID_NIGHT_MILI + 3600 * 1000 * 11 + 1000 * 60 * 48 // for testing
return now > TODAY_MID_NIGHT_MILI // for testing
}, { timeout: 1000 * 60 * 10, timeoutMsg: 'Class should be able to book in 10 min', interval: 200 })
// browser.$(function) seems can't access variables outside so need to use browser.execute
const hasClass = await browser.execute((classTime) => {
const xpath = `//span[contains(text(),'${classTime}')]`
const timeSpan = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const classDiv = timeSpan?.parentElement?.parentElement;
if (classDiv) {
classDiv.click()
return true
}
else {
return false
}
}, TARGET.string)
if (!hasClass) {
console.log('no class found for', classStartTime)
process.exit()
}
// book it
const bookBtn = await browser.$('.bigSize.f-fr')
await bookBtn.click()
// actually book it
// const confirmBtn = await browser.$(".btn.u-btn.u-btn-main")
// await confirmBtn.click()
await browser.pause(2000);
console.log('done!')
process.exit(0);
})();