· 8 years ago · Dec 22, 2017, 01:00 PM
1package main
2
3import (
4 "fmt"
5 "github.com/tebeka/selenium"
6 "github.com/tebeka/selenium/sauce"
7 "github.com/blang/semver"
8 "net"
9 "flag"
10 "log"
11 "time"
12 "errors"
13 "github.com/tebeka/selenium/firefox"
14 "math/rand"
15 "strings"
16)
17
18const (
19 vkAuthUrl string = "https://oauth.vk.com/authorize?client_id=5614546&scope=photos,audio,video,docs,notes,pages,status,offers,questions,wall,groups,messages,email,notifications,stats,ads,offline,docs,pages,stats,notifications&response_type=token&redirect_uri=http://oauth.vk.com/blank.html&display=page"
20)
21
22var (
23 firefoxBinarySelenium3 = flag.String("firefox_binary_for_selenium3", "vendor/firefox-nightly/firefox", "The name of the Firefox binary for Selenium 3 tests or the path to it. If the name does not contain directory separators, the PATH will be searched.")
24 geckoDriverPath = flag.String("geckodriver_path", "vendor/geckodriver-v0.18.0-linux64", "The path to the geckodriver binary. If empty of the file is not present, the Geckodriver tests will not be run.")
25 startFrameBuffer = flag.Bool("start_frame_buffer", true, "If true, start an Xvfb subprocess and run the browsers in that X server.")
26
27 vkLoginUrl = flag.String("vk_login_url", "https://vk.com/login", "Vk Login Url, default: https://vk.com/login")
28 emailSelector = flag.String("email_selector", "#email", "Email Selector, default: #email")
29 passSelector = flag.String("pass_selector", "#pass", "Email Selector, default: #pass")
30 loginButtonSelector = flag.String("login_button_selector", "#login_button", "Pass Selector, default: #login_button")
31 pageNameSelector = flag.String("page_name_selector", ".page_name", "Page name Selector, default: .page_name")
32
33 vkUserEmail = flag.String("vk_user_email", "*@gmail.com", "Usage for email input")
34 vkUserPass = flag.String("vk_user_pass", "*", "Usage for pass input")
35
36 caps selenium.Capabilities
37 service *selenium.Service
38 wd selenium.WebDriver
39
40 vkUserInfo VkUserInfo
41)
42
43type config struct {
44 addr, browser, path string
45 sauce *sauce.Capabilities
46 seleniumVersion semver.Version
47 serviceOptions []selenium.ServiceOption
48}
49
50type VkUserInfo struct {
51 email, password string
52}
53
54func main() {
55
56 var err error
57
58 fmt.Println("Start script...")
59
60 // ПарÑим заполненные ключи из командной Ñтроки
61 flag.Parse()
62
63 // загружаем данные Ñ„Ñйка Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° по нему
64 loadVkUserInfo()
65
66 // загружаем вÑе Ð´Ð»Ñ Firefox драйвера
67 loadFirefoxDriver(*geckoDriverPath, config{
68 path: *firefoxBinarySelenium3,
69 })
70
71 /*if err = checkUserAgent(); err != nil {
72 time.Sleep(time.Second * 1000)
73 return
74 }*/
75
76 // Проходим авторизацию в вк
77 if err = authVk(); err != nil {
78 log.Fatalln(err)
79 //log.Println(err)
80 }
81}
82
83func loadVkUserInfo() {
84 vkUserInfo.email = *vkUserEmail
85 vkUserInfo.password = *vkUserPass
86}
87
88func authVk() (error) {
89 var err error
90
91 // Отложенное закрытие драйвера и ÑервиÑа.
92 defer service.Stop()
93 defer wd.Quit()
94
95 // Переходим на форму авторизации
96 if err = loadVkLoginPage(); err != nil {
97 return err
98 }
99
100 if err = printCurrentUrl(); err != nil {
101 return err
102 }
103
104 // ЗаполнÑем поле email
105 if err = fillEmail(); err != nil {
106 return err
107 }
108
109 time.Sleep(500 * time.Millisecond)
110
111 // ЗаполнÑем поле pass
112 if err = fillPassword(); err != nil {
113 return err
114 }
115
116 time.Sleep(500 * time.Millisecond)
117
118 //return errors.New("before submitForm")
119 //log.Fatalln("before submitForm")
120
121 // Сабмитим форму авторизации Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð²Ðº
122 if err = submitForm(); err != nil {
123 return err
124 }
125
126 time.Sleep(1500 * time.Millisecond)
127
128 //return errors.New("after submitForm")
129 //log.Fatalln("after submitForm")
130
131 if err = checkLoginSuccess(); err != nil {
132 return err
133 }
134
135 // Переходим на Ñтраницу (Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾ÐºÐµÐ½Ð°)|(привÑзку Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ðº профилю и получение токена)
136 if err = loadAuthVkPage(); err != nil {
137 return err
138 }
139
140 time.Sleep(1500 * time.Millisecond)
141
142 if err = loadAuthToken(); err != nil {
143 return err
144 }
145
146 return nil
147}
148
149func loadAuthToken() (error) {
150 var (
151 err error
152 acceptButton selenium.WebElement
153 currentUrl string
154 accessToken string
155 )
156
157 for i := 0; i < 5; i++ {
158 acceptButton, err = wd.FindElement(selenium.ByCSSSelector, ".flat_button.fl_r.button_indent")
159 if err != nil {
160 err = errors.New("WebDriver can not acceptButton, returned error: " + err.Error())
161 time.Sleep(1 * time.Second)
162 continue
163 }
164
165 break
166 }
167
168 if err == nil {
169 if err = acceptButton.Click(); err != nil {
170 return err
171 }
172
173 currentUrl, err = getCurrentUrl()
174 if err != nil {
175 return err
176 }
177 } else {
178 currentUrl, err = getCurrentUrl()
179 if err != nil {
180 return err
181 }
182 }
183
184 accessToken = getAccessToken(currentUrl)
185 if accessToken == "" {
186 return errors.New("Access token is empty")
187 }
188
189 log.Println(accessToken)
190
191 return nil
192}
193
194func loadVkLoginPage() (error) {
195 var err error
196
197 if err = wd.Get(*vkLoginUrl); err != nil {
198 //log.Fatalf("WebDriver can not Get(someUrl) returned error: %v", err)
199 return errors.New("WebDriver can not Get(someUrl) returned error: " + err.Error())
200 }
201
202 if err = setPageLoadTimeout(); err != nil {
203 //log.Fatalln(err)
204 return err
205 }
206
207 return nil
208}
209
210func printCurrentUrl() (error) {
211 currentURL, err := getCurrentUrl()
212 if err != nil {
213 //log.Fatalln("WebDriver can not CurrentURL() returned error: %v", err)
214 return err
215 }
216
217 log.Println("currentURL: ", currentURL)
218
219 return nil
220}
221
222func getCurrentUrl() (string, error) {
223 currentURL, err := wd.CurrentURL()
224 if err != nil {
225 return "", errors.New("WebDriver can not CurrentURL() returned error: " + err.Error())
226 }
227
228 return currentURL, nil
229}
230
231func fillEmail() (error) {
232 emailField, err := wd.FindElement(selenium.ByCSSSelector, *emailSelector)
233 if err != nil {
234 //log.Fatalf("WebDriver can not FindElement, returned error: %v", err)
235 return errors.New("WebDriver can not FindElement, returned error: " + err.Error())
236 }
237
238 if err := emailField.Clear(); err != nil {
239 //log.Fatalf("WebDriver can not Clear emailField, returned error: %v", err)
240 return errors.New("WebDriver can not Clear emailField, returned error: " + err.Error())
241 }
242
243 err = emailField.SendKeys(vkUserInfo.email)
244 if err != nil {
245 //log.Fatalf("WebDriver can not SendKeys to emailField, returned error: %v", err)
246 return errors.New("WebDriver can not SendKeys to emailField, returned error: " + err.Error())
247 }
248
249 return nil
250}
251
252func fillPassword() (error) {
253 passField, err := wd.FindElement(selenium.ByCSSSelector, *passSelector)
254 if err != nil {
255 //log.Fatalf("WebDriver can not FindElement, returned error: %v", err)
256 return errors.New("WebDriver can not FindElement, returned error: " + err.Error())
257 }
258
259 if err := passField.Clear(); err != nil {
260 //log.Fatalf("WebDriver can not Clear passField, returned error: %v", err)
261 return errors.New("WebDriver can not Clear passField, returned error: " + err.Error())
262 }
263
264 err = passField.SendKeys(vkUserInfo.password)
265 if err != nil {
266 //log.Fatalf("WebDriver can not SendKeys to passField, returned error: %v", err)
267 return errors.New("WebDriver can not SendKeys to passField, returned error: " + err.Error())
268 }
269
270 //printPassInputValue(passField)
271
272 return nil
273}
274
275func submitForm() (error) {
276 btn, err := wd.FindElement(selenium.ByCSSSelector, *loginButtonSelector)
277 if err != nil {
278 //log.Fatalln(err)
279 return err
280 }
281
282 if err := btn.Click(); err != nil {
283 //log.Fatalln(err)
284 return err
285 }
286
287 return nil
288}
289
290func checkLoginSuccess() (error) {
291 log.Println("start checkLoginSuccess")
292
293 var (
294 err error
295 pageName selenium.WebElement
296 pageNameText string
297 )
298
299 for i := 0; i < 5; i++ {
300 pageName, err = wd.FindElement(selenium.ByCSSSelector, *pageNameSelector)
301 if err != nil {
302 time.Sleep(1 * time.Second)
303 continue
304 }
305
306 break
307 }
308
309 if err != nil {
310 return err
311 }
312
313 for i := 0; i < 5; i++ {
314 pageNameText, err = pageName.Text()
315 if err != nil {
316 continue
317 }
318 if pageNameText != "Waiting for remote server..." {
319 break
320 }
321 time.Sleep(1 * time.Second)
322 }
323
324 if err != nil {
325 return err
326 }
327
328 log.Println(pageNameText)
329
330 return nil
331}
332
333func loadAuthVkPage() (error) {
334 var err error
335
336 if err = wd.Get(vkAuthUrl); err != nil {
337 //log.Fatalln(err)
338 return err
339 }
340
341 /*if err = setPageLoadTimeout(); err != nil {
342 //log.Fatalln(err)
343 return err
344 }*/
345
346 return nil
347}
348
349func printPassInputValue(passField selenium.WebElement) {
350 var output string
351 for {
352 output, err := passField.GetAttribute("value")
353 if err != nil {
354 log.Fatalln(err)
355 }
356 if output != "Waiting for remote server..." {
357 break
358 }
359 time.Sleep(time.Millisecond * 100)
360 }
361 fmt.Println("output: ", output)
362}
363
364func setPageLoadTimeout() (error) {
365 if err := wd.SetPageLoadTimeout(1 * time.Second); err != nil {
366 //log.Fatalf("wd.SetImplicitWaitTimeout() returned error: %v", err)
367 return errors.New("wd.SetImplicitWaitTimeout() returned error: " + err.Error())
368 }
369
370 return nil
371}
372
373func loadFirefoxDriver(webDriverPath string, c config) {
374 c.browser = "firefox"
375
376 if *startFrameBuffer {
377 c.serviceOptions = append(c.serviceOptions, selenium.StartFrameBuffer())
378 }
379
380 port, err := pickUnusedPort()
381 if err != nil {
382 log.Fatalf("pickUnusedPort() returned error: %v", err)
383 }
384 c.addr = fmt.Sprintf("http://127.0.0.1:%d", port)
385
386 /*if s, err := os.Stat(c.path); err != nil || !s.Mode().IsRegular() {
387 if path, err := exec.LookPath(c.path); err == nil {
388 c.path = path
389 } else {
390 t.Skipf("Skipping Firefox tests because binary %q not found", c.path)
391 }
392 }*/
393
394 /*if testing.Verbose() {
395 SetDebug(true)
396 c.serviceOptions = append(c.serviceOptions, Output(os.Stderr))
397 }*/
398
399 service, err = selenium.NewGeckoDriverService(webDriverPath, port, c.serviceOptions...)
400 if err != nil {
401 log.Fatalln(err)
402 }
403 //defer service.Stop()
404
405 wd, err = selenium.NewRemote(getFirefoxCapabilities(), c.addr)
406 if err != nil {
407 log.Fatalln(err)
408 }
409 //defer wd.Quit()
410
411
412
413 /*runFirefoxSubTests(t, c)
414
415 if err := s.Stop(); err != nil {
416 t.Fatalf("Error stopping the Selenium service: %v", err)
417 }*/
418}
419
420func getFirefoxCapabilities() (selenium.Capabilities) {
421 caps = selenium.Capabilities{"browserName": "firefox"}
422
423 f, ok := caps[firefox.CapabilitiesKey].(firefox.Capabilities)
424 if !ok || f.Prefs == nil {
425 f.Prefs = make(map[string]interface{})
426 }
427
428 f.Prefs["general.useragent.override"] = getRandomUserAgent()
429 caps.AddFirefox(f)
430
431 return caps
432}
433
434func getRandomUserAgent() (string) {
435
436 userAgentList := map[int]string{
437 0: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36",
438 1: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36",
439 2: "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36",
440
441 3: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0",
442 4: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20130331 Firefox/21.0",
443 5: "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0",
444 }
445
446 randomKey := randomInt(0, len(userAgentList) - 1);
447
448 return userAgentList[randomKey]
449}
450
451func randomInt(min, max int) int {
452 rand.Seed(time.Now().Unix())
453 return rand.Intn(max - min) + min
454}
455
456func pickUnusedPort() (int, error) {
457 addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
458 if err != nil {
459 return 0, err
460 }
461
462 l, err := net.ListenTCP("tcp", addr)
463 if err != nil {
464 return 0, err
465 }
466 port := l.Addr().(*net.TCPAddr).Port
467 if err := l.Close(); err != nil {
468 return 0, err
469 }
470 return port, nil
471}
472
473
474func checkUserAgent() (error) {
475 var err error
476
477 if err = wd.Get("http://www.useragentstring.com/"); err != nil {
478 //log.Fatalf("WebDriver can not Get(someUrl) returned error: %v", err)
479 return errors.New("WebDriver can not Get(someUrl) returned error: " + err.Error())
480 }
481
482 if err = setPageLoadTimeout(); err != nil {
483 return err
484 }
485
486 userAgentField, err := wd.FindElement(selenium.ByCSSSelector, "#uas_textfeld")
487 if err != nil {
488 //log.Fatalf("WebDriver can not FindElement, returned error: %v", err)
489 return errors.New("WebDriver can not userAgentField, returned error: " + err.Error())
490 }
491
492 var userAgentFieldText string
493 for {
494 userAgentFieldText, err = userAgentField.Text()
495 if err != nil {
496 return err
497 }
498 if userAgentFieldText != "Waiting for remote server..." {
499 break
500 }
501 time.Sleep(time.Millisecond * 100)
502 }
503
504 fmt.Println("userAgentFieldText: ", userAgentFieldText)
505
506 return nil
507}
508
509func getAccessToken(oauthVKUrl string) (string) {
510 if !strings.HasPrefix(oauthVKUrl, "https://oauth.vk.com/blank.html#") || !strings.Contains(oauthVKUrl, "access_token=") {
511 return ""
512 }
513
514 oauthVKUrl = strings.Replace(oauthVKUrl, "https://oauth.vk.com/blank.html#", "", 1)
515
516 if (strings.Contains(oauthVKUrl, "&")) {
517 for _, param := range strings.Split(oauthVKUrl, "&") {
518 if strings.HasPrefix(param, "access_token=") {
519 oauthVKUrl = strings.Replace(param, "access_token=", "", 1)
520 }
521 }
522 } else {
523 oauthVKUrl = strings.Replace(oauthVKUrl, "access_token=", "", 1)
524 }
525
526 return oauthVKUrl
527}