Skip to content

Commit

Permalink
Merge pull request #38 from DanielFillol/daniel
Browse files Browse the repository at this point in the history
Datepicker
  • Loading branch information
DanielFillol authored Aug 17, 2024
2 parents 7baebfe + 3fce5ee commit e996a55
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
116 changes: 116 additions & 0 deletions goSpider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"io/ioutil"
"log"
"os"
"regexp"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -1020,6 +1022,120 @@ func (nav *Navigator) MakeElementVisible(selector string) error {
return nil
}

// Datepicker deals with date-picker elements on websites by receiving a date, calculates the amount of time it needs to go back in the picker and finally selects a day.
//
// date: string in the format "dd/mm/aaaa"
// calendarButtonSelector: the css selector of the data-picker
// calendarButtonGoBack: the css selector of the go back button
// calendarButtonsTableXpath: the xpath of the days table example: "//*[@id="ui-datepicker-div"]/table/tbody/tr";
// calendarButtonTR: the css selector of the days table row, example: "//*[@id="ui-datepicker-div"]/table/tbody/tr"
func (nav *Navigator) Datepicker(date, calendarButtonSelector, calendarButtonGoBack, calendarButtonsTableXpath, calendarButtonTR string) error {
regex := `^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/[0-9]{4}$`
r := regexp.MustCompile(regex)
if r.MatchString(date) == false {
return errors.New("date does not match with dd/mm/aaaa")
}

parsedDate, err := time.Parse("02/01/2006", date)
if err != nil {
return errors.New("error parsing date: " + err.Error())
}

today := time.Now().Format("02/01/2006")
parseToday, err := time.Parse("02/01/2006", today)
if err != nil {
return errors.New("error parsing today's date: " + err.Error())
}

// Ensure startDate is before endDate
if parsedDate.After(parseToday) {
return errors.New("date must be older then today")
}
years, months, _ := calculateDateDifference(parsedDate, parseToday)

err = nav.ClickButton(calendarButtonSelector)
if err != nil {
return err
}

i := 0
for {
err = chromedp.Run(nav.Ctx, chromedp.Click(calendarButtonGoBack))
if err != nil {
break
}
i++
if i == ((years * 12) + months) {
break
}
}

err = nav.WaitForElement(calendarButtonsTableXpath, time.Minute)
if err != nil {
return err
}

pageSource, err := nav.GetPageSource()
if err != nil {
return err
}

tt, err := htmlquery.Find(pageSource, calendarButtonsTableXpath)
if err != nil {
return err
}

for k, node := range tt {
for l := 1; l < 8; l++ {
day, err := ExtractText(node, "td["+strconv.Itoa(l)+"]", "")
if err != nil {
return err
}
if day == strconv.Itoa(parsedDate.Day()) {
err = nav.ClickButton(calendarButtonsTableXpath + "[" + strconv.Itoa(k+1) + "]/td[" + strconv.Itoa(l) + "]")
if err != nil {
return errors.New("error clicking button on calendar button: " + calendarButtonTR + "(" + strconv.Itoa(k) + ") > td:nth-child(" + strconv.Itoa(l) + "). Error code: " + err.Error())
} else {
return nil
}
}

}

}
return errors.New("could not pick date")
}
func calculateDateDifference(startDate, endDate time.Time) (int, int, int) {
years := endDate.Year() - startDate.Year()
months := int(endDate.Month()) - int(startDate.Month())
days := endDate.Day() - startDate.Day()

// Adjust the difference if necessary
if days < 0 {
// Borrow days from the previous month
months--
previousMonth := endDate.AddDate(0, -1, 0)
days += previousMonth.Day()
}

if months < 0 {
// Borrow months from the previous year
years--
months += 12
}

return years, months, days
}

func PrintHtml(pageSource *html.Node) (string, error) {
var sb strings.Builder
err := html.Render(&sb, pageSource)
if err != nil {
return "", err
}
return sb.String(), nil
}

// Close closes the Navigator instance and releases resources.
// Example:
//
Expand Down
61 changes: 61 additions & 0 deletions goSpider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,67 @@ func TestMakeElementVisible(t *testing.T) {
}
}

func TestPrintHtml(t *testing.T) {
server := startTestServer()
defer server.Close()

nav := setupNavigator(t)
defer nav.Close()

err := nav.OpenURL(server.URL + "/test.html")
if err != nil {
t.Errorf("OpenURL error: %v", err)
}

ps, err := nav.GetPageSource()
if err != nil {
t.Errorf("GetPageSource error: %v", err)
}

s, err := PrintHtml(ps)
if err != nil {
t.Errorf("PrintHtml error: %v", err)
}

fmt.Println(s)

}

func TestDatepicker(t *testing.T) {
nav := NewNavigator("", false)

err := nav.OpenURL("https://www.tjrs.jus.br/buscas/jurisprudencia/?conteudo_busca=ementa_completa&q_palavra_chave=&aba=jurisprudencia&q=&conteudo_busca=ementa_completa")
if err != nil {
t.Errorf("OpenURL error: %v", err)
return
}

err = nav.WaitForElement("#datas_julgamento_publicacao_div > div:nth-child(2) > div.col-md-4.col-xs-12.dataPublicacaoContainer > div > div > div.recuo_esquerdo_10px.col-md-5.col-xs-5 > div > input", time.Minute)
if err != nil {
t.Errorf("WaitForElement error: %v", err)
return
}

err = nav.Datepicker("01/01/2000", "#datas_julgamento_publicacao_div > div:nth-child(2) > div.col-md-4.col-xs-12.dataPublicacaoContainer > div > div > div.recuo_esquerdo_10px.col-md-5.col-xs-5 > div > span > i", "#ui-datepicker-div > div > a.ui-datepicker-prev.ui-corner-all > span", "//*[@id=\"ui-datepicker-div\"]/table/tbody/tr", "#ui-datepicker-div > table > tbody > tr:nth-child")
if err != nil {
t.Errorf("Datepicker error: %v", err)
return
}

err = nav.Datepicker("31/12/2000", "#datas_julgamento_publicacao_div > div:nth-child(2) > div.col-md-4.col-xs-12.dataPublicacaoContainer > div > div > div:nth-child(3) > div > span", "#ui-datepicker-div > div > a.ui-datepicker-prev.ui-corner-all > span", "//*[@id=\"ui-datepicker-div\"]/table/tbody/tr", "#ui-datepicker-div > table > tbody > tr:nth-child")
if err != nil {
t.Errorf("Datepicker error: %v", err)
return
}

start := time.Now()
for {
if time.Since(start) > time.Minute {
break
}
}
}

// Won't pass on test because 2FA requires input on the terminal by the user, for that reason alone the test will fail
//// TestLoginGoogle tests google single logon
//func TestLoginGoogle(t *testing.T) {
Expand Down

0 comments on commit e996a55

Please sign in to comment.