How to find an item - selenium

I'm trying to find an element on the page, but it doesn't work out what could be the reason?
package main
import (
"github.com/tebeka/selenium"
"log"
"time"
)
func main() {
caps := selenium.Capabilities{
"browserName": "chrome",
}
wd, err := selenium.NewRemote(caps, "http://localhost:4444/wd/hub")
if err != nil{
log.Fatal(err)
}
defer func() {
if err := wd.Quit(); err != nil {
log.Fatal(err)
}
}()
if err := wd.SetPageLoadTimeout(time.Second * 10); err != nil {
log.Fatal(err)
}
if err = wd.SetImplicitWaitTimeout(time.Second * 10); err != nil {
log.Fatal(err)
}
if err = wd.Get("https://www.facebook.com/ads/library/?active_status=all&ad_type=political_and_issue_ads&country=ALL&sort_data[direction]=desc&sort_data[mode]=relevancy_monthly_grouped"); err != nil {
log.Fatal(err)
}
title, err := wd.Title()
if err != nil {
log.Fatalln(err)
}
log.Println(title)
elem, err := wd.FindElement(selenium.ByXPATH, "//*[#id=\"content\"]/div/div/div[3]/div/div[4]/div")
if err != nil {
log.Fatal(err)
}
log.Println(elem.Text())
}
gives an error message:
no such element: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="content"]/div/div/div[3]/div/div[4]/div"}
The hub was raised in docker. Image https://hub.docker.com/r/selenium/standalone-chrome

Just try to not use XPATHs with Selenium if you can.
Search for it using .ByTag and look for a unique property of your element to find it. Never rely on XPATHs, classes or even IDs for famous websites since they often change.
Check my answer here: How to click on the Ask to join button within https://meet.google.com using Selenium and Python?

Related

Transaction in Golang with PGX

I am currently in the process of creating a little Go App. Right now I am working on the DB part. The Library I use is this one: https://github.com/jackc/pgx
The problem I have is that every time I try to execute the database read, it tells me that my 'conn is busy'. I read about using a pgxpool instead of a single connection, but it still does not work. What am I doing wrong?
func (postgre *PostgreClient) read(query string) (pgx.Row, error) {
client, err := postgre.client.Acquire(context.TODO())
transaction, err := client.BeginTx(context.TODO(), pgx.TxOptions{})
if err != nil {
return nil, err
}
defer transaction.Rollback(context.TODO())
rows := transaction.QueryRow(context.TODO(), query)
if err != nil {
return nil, err
}
err = transaction.Commit(context.TODO())
return rows, err
}
Thanks in advance.
You have to scan the row before you commit the transaction.
If you want the handling of the transaction to remain within the function you can pass an interface that does the scanning also inside the function.
For example:
// implemented by *sql.Row & *sql.Rows
type Row interface {
Scan(dst ...interface{}) error
}
// implemented by your "models"
type RowScanner interface {
ScanRow(r Row) error
}
type User struct {
Id int
Email string
}
func (u *User) ScanRow(r Row) error {
return r.Scan(
&u.Id,
&u.Email,
)
}
func (postgre *PostgreClient) read(query string, rs RowScanner) (err error) {
conn, err := postgre.client.Acquire(context.TODO())
if err != nil {
return err
}
defer conn.Release()
tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{})
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback(context.TODO())
} else {
tx.Commit(context.TODO())
}
}()
row := tx.QueryRow(context.TODO(), query)
if err != nil {
return nil, err
}
return rs.ScanRow(row)
}
u := new(User)
if err := pg.read("select id, email from users limit 1", u); err != nil {
panic(err)
}
For scanning a list of models:
type UserList []*User
func (ul *UserList) ScanRow(r Row) error {
u := new(User)
if err := u.ScanRow(r); err != nil {
return err
}
*ul = append(*ul, u)
return nil
}
func (postgre *PostgreClient) list(query string, rs RowScanner) (err error) {
conn, err := postgre.client.Acquire(context.TODO())
if err != nil {
return err
}
defer conn.Release()
tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{})
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback(context.TODO())
} else {
tx.Commit(context.TODO())
}
}()
rows, err := tx.Query(context.TODO(), query)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
if err := rs.ScanRow(rows); err != nil {
return err
}
}
return rows.Err()
}
ul := new(UserList)
if err := pg.list("select id, email from users", ul); err != nil {
panic(err)
}

How to use os.Open()'s return value as the third parameter of http.Post() and set Content-Length?

The third parameter of http.Post() allows io.Reader and that means the return value of os.Open() should work. But the below code gets unexpected result, in other words, it won't set Content-Length properly. Perhaps File type doesn't implement something. Is there any proper way to set Content-Length with *File?
package main
import (
"bytes"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"os"
)
var sample = []byte(`hello`)
func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Header)
if int(r.ContentLength) != len(sample) {
log.Fatal("Unexpected Content-Length:", r.ContentLength)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer ts.Close()
file, err := ioutil.TempFile(os.TempDir(), "")
if err != nil {
log.Fatal(err)
}
defer os.Remove(file.Name())
file.Write(sample)
// This works
buf, err := ioutil.ReadFile(file.Name())
if err != nil {
log.Fatal(err)
}
_, err = http.Post(ts.URL, "application/octet-stream", bytes.NewBuffer(buf))
if err != nil {
log.Fatal(err)
}
// This looks fine in my opinion, though it doesn't set Content-Length
f, err := os.Open(file.Name())
if err != nil {
log.Fatal(err)
}
_, err = http.Post(ts.URL, "application/octet-stream", f)
if err != nil {
log.Fatal(err)
}
}
Output:
2009/11/10 23:00:00 map[Content-Type:[application/octet-stream] Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1] Content-Length:[5]]
2009/11/10 23:00:00 map[Content-Type:[application/octet-stream] Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
2009/11/10 23:00:00 Unexpected Content-Length:-1
https://play.golang.org/p/hJLN2H9Y9p
If you look at source for NewRequest you can see that contentLength is handled specially for specific input types, and the file reader isn't one of them. You'll have to manually set the Content-Length header if that's important [chunked should also work fine, unless you're sending to an old server impl].
If you want to add a add the Content-Length, you need to stat the file to get the size. The ContentLength isn't calculated automatically because an os.File may not have a useful size.
f, err := os.Open(file.Name())
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest("POST", ts.URL, f)
if err != nil {
log.Fatal(err)
}
stat, err := f.Stat()
if err != nil {
log.Fatal(err)
}
req.ContentLength = stat.Size()
req.Header.Set("Content-Type", "application/octet-stream")
resp, err = http.Do(req)
...

How to watch docker event with engine-api

Anybody who know how to watch docker event with engine-api the go client for docker, or has any example for this ?
I know How to do this now :
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/events"
"golang.org/x/net/context"
)
func main() {
defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
cli, err := client.NewClient("http://172.17.150.101:2376", "v1.24", nil, defaultHeaders)
if err != nil {
panic(err)
}
options := types.ContainerListOptions{All: true}
containers, err := cli.ContainerList(context.Background(), options)
if err != nil {
panic(err)
}
for _, c := range containers {
fmt.Println(c.ID)
}
body, err := cli.Events(context.Background(), types.EventsOptions{})
if err != nil {
log.Fatal(err)
}
dec := json.NewDecoder(body)
for {
var event events.Message
err := dec.Decode(&event)
if err != nil && err == io.EOF {
break
}
log.Println(event)
}
}

Can I get EXPLAIN ANALYZE output through the lib/pq Go SQL driver?

I'd like to be able to evaluate my queries inside my app, which is in Go and using the github.com/lib/pq driver. Unfortunately, neither the [lib/pq docs][1] nor the [database/sql][2] docs seem to say anything about this, and nothing in the database/sql interfaces suggests this is possible.
Has anyone found a way to get this output?
Typical EXPLAIN ANALYZE returns several rows, so you can do it with simple sql.Query. Here is an example:
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"log"
)
func main() {
db, err := sql.Open("postgres", "user=test dbname=test sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query("EXPLAIN ANALYZE SELECT * FROM accounts ORDER BY slug")
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var s string
if err := rows.Scan(&s); err != nil {
log.Fatal(err)
}
fmt.Println(s)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}

How can I use the "compress/gzip" package to gzip a file?

I'm new to Go, and can't figure out how to use the compress/gzip package to my advantage. Basically, I just want to write something to a file, gzip it and read it directly from the zipped format through another script. I would really appreciate if someone could give me an example on how to do this.
All the compress packages implement the same interface. You would use something like this to compress:
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close()
And this to unpack:
r, err := gzip.NewReader(&b)
io.Copy(os.Stdout, r)
r.Close()
Pretty much the same answer as Laurent, but with the file io:
import (
"bytes"
"compress/gzip"
"io/ioutil"
)
// ...
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close() // You must close this first to flush the bytes to the buffer.
err := ioutil.WriteFile("hello_world.txt.gz", b.Bytes(), 0666)
For the Read part, something like the useful ioutil.ReadFile for .gz files could be :
func ReadGzFile(filename string) ([]byte, error) {
fi, err := os.Open(filename)
if err != nil {
return nil, err
}
defer fi.Close()
fz, err := gzip.NewReader(fi)
if err != nil {
return nil, err
}
defer fz.Close()
s, err := ioutil.ReadAll(fz)
if err != nil {
return nil, err
}
return s, nil
}
Here the func for unpack gzip file to destination file:
func UnpackGzipFile(gzFilePath, dstFilePath string) (int64, error) {
gzFile, err := os.Open(gzFilePath)
if err != nil {
return 0, fmt.Errorf("open file %q to unpack: %w", gzFilePath, err)
}
dstFile, err := os.OpenFile(dstFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660)
if err != nil {
return 0, fmt.Errorf("create destination file %q to unpack: %w", dstFilePath, err)
}
defer dstFile.Close()
ioReader, ioWriter := io.Pipe()
defer ioReader.Close()
go func() { // goroutine leak is possible here
gzReader, _ := gzip.NewReader(gzFile)
// it is important to close the writer or reading from the other end of the
// pipe or io.copy() will never finish
defer func(){
gzFile.Close()
gzReader.Close()
ioWriter.Close()
}()
io.Copy(ioWriter, gzReader)
}()
written, err := io.Copy(dstFile, ioReader)
if err != nil {
return 0, err // goroutine leak is possible here
}
return written, nil
}
I decided to combine ideas from others answers and just provide a full example program. Obviously there are many different ways to do the same thing. This is just one way:
package main
import (
"compress/gzip"
"fmt"
"io/ioutil"
"os"
)
var zipFile = "zipfile.gz"
func main() {
writeZip()
readZip()
}
func writeZip() {
handle, err := openFile(zipFile)
if err != nil {
fmt.Println("[ERROR] Opening file:", err)
}
zipWriter, err := gzip.NewWriterLevel(handle, 9)
if err != nil {
fmt.Println("[ERROR] New gzip writer:", err)
}
numberOfBytesWritten, err := zipWriter.Write([]byte("Hello, World!\n"))
if err != nil {
fmt.Println("[ERROR] Writing:", err)
}
err = zipWriter.Close()
if err != nil {
fmt.Println("[ERROR] Closing zip writer:", err)
}
fmt.Println("[INFO] Number of bytes written:", numberOfBytesWritten)
closeFile(handle)
}
func readZip() {
handle, err := openFile(zipFile)
if err != nil {
fmt.Println("[ERROR] Opening file:", err)
}
zipReader, err := gzip.NewReader(handle)
if err != nil {
fmt.Println("[ERROR] New gzip reader:", err)
}
defer zipReader.Close()
fileContents, err := ioutil.ReadAll(zipReader)
if err != nil {
fmt.Println("[ERROR] ReadAll:", err)
}
fmt.Printf("[INFO] Uncompressed contents: %s\n", fileContents)
// ** Another way of reading the file **
//
// fileInfo, _ := handle.Stat()
// fileContents := make([]byte, fileInfo.Size())
// bytesRead, err := zipReader.Read(fileContents)
// if err != nil {
// fmt.Println("[ERROR] Reading gzip file:", err)
// }
// fmt.Println("[INFO] Number of bytes read from the file:", bytesRead)
closeFile(handle)
}
func openFile(fileToOpen string) (*os.File, error) {
return os.OpenFile(fileToOpen, openFileOptions, openFilePermissions)
}
func closeFile(handle *os.File) {
if handle == nil {
return
}
err := handle.Close()
if err != nil {
fmt.Println("[ERROR] Closing file:", err)
}
}
const openFileOptions int = os.O_CREATE | os.O_RDWR
const openFilePermissions os.FileMode = 0660
Having a full example like this should be helpful for future reference.
To compress any Go object of interface type as input
func compress(obj interface{}) ([]byte, error) {
var b bytes.Buffer
objBytes, err := json.Marshal(obj)
if err != nil {
return nil, err
}
gz := gzip.NewWriter(&b)
defer gz.Close() //NOT SUFFICIENT, DON'T DEFER WRITER OBJECTS
if _, err := gz.Write(objBytes); err != nil {
return nil, err
}
// NEED TO CLOSE EXPLICITLY
if err := gz.Close(); err != nil {
return nil, err
}
return b.Bytes(), nil
}
To decompress the same,
func decompress(obj []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(obj))
if err != nil {
return nil, err
}
defer r.Close()
res, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return res, nil
}
Note, ioutil.ReadAll(r) returns io.EOF or io.ErrUnexpectedEOF if you do not close the Writer object after writing. I assumed defer on Close() would close the object properly, but it won't. Don't defer writer objects.