Skip to content

Commit

Permalink
feat: enabling the extraction of a specific selection from an element
Browse files Browse the repository at this point in the history
  • Loading branch information
Azhovan committed Dec 29, 2023
1 parent 7d131d6 commit 50d21c8
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
12 changes: 12 additions & 0 deletions js/modules/k6/html/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ func (e Element) IsSameNode(v goja.Value) bool {
return false
}

// Selection returns a Selection object based on the current Element.
//
// This function is used to create a Selection object that represents the same HTML
// content as the Element. It is useful for performing operations or manipulations
// on the HTML content within the scope of this Element.
//
// Example:
// sel := element.Selection()
func (e Element) Selection() Selection {
return Selection{rt: e.sel.rt, sel: e.sel.sel, URL: e.sel.URL}
}

func (e Element) GetElementsByClassName(name string) []goja.Value {
return elemList(Selection{e.sel.rt, e.sel.sel.Find("." + name), e.sel.URL})
}
Expand Down
9 changes: 9 additions & 0 deletions js/modules/k6/html/element_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,15 @@ func TestElement(t *testing.T) {
assert.Contains(t, nodes[3].Export().(Element).TextContent(), "Maecenas augue ligula")
}
})
t.Run("Selection", func(t *testing.T) {
t.Parallel()
rt := getTestRuntimeWithDoc(t, testHTMLElem)

v, err := rt.RunString(`doc.find('div').get(0).selection().find('h2').text()`)
if assert.NoError(t, err) {
assert.Equal(t, "Nullam id nisi eget ex pharetra imperdiet.", v.String())
}
})
t.Run("ClassList", func(t *testing.T) {
t.Parallel()
rt := getTestRuntimeWithDoc(t, testHTMLElem)
Expand Down
32 changes: 32 additions & 0 deletions js/modules/k6/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,38 @@ func (s Selection) Last() Selection {
return Selection{s.rt, s.sel.Last(), s.URL}
}

// FromElement creates a new Selection based on a specified Element.
//
// This function is useful for creating a new Selection object that
// encapsulates the same HTML structure as the provided Element. It
// is particularly helpful when you need to perform further operations
// or manipulations on the HTML content within the scope of this Element.
// If the provided value is not an Element, an empty Selection is returned.
//
// Example:
// sel := existingSelection.FromElement(jsElement)
func (s Selection) FromElement(v goja.Value) Selection {
elm, ok := v.Export().(Element)
if !ok {
// Return an empty Selection if the value is not an Element
return s.emptySelection()
}

return Selection{rt: s.rt, sel: elm.sel.sel, URL: s.URL}
}

// Locator selects HTML elements based on a CSS selector or XPath.
//
// This method is designed to provide a consistent way of selecting elements,
// similar to how 'page.locator' works in the 'k6-browser'. It uses goquery
// to perform the selection based on the given selector string.
//
// Example:
// sel := mySelection.Locator(".myClass")
func (s Selection) Locator(selector string) Selection {
return Selection{s.rt, s.sel.Find(selector), s.URL}
}

func (s Selection) Contents() Selection {
return Selection{s.rt, s.sel.Contents(), s.URL}
}
Expand Down
21 changes: 21 additions & 0 deletions js/modules/k6/html/html_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,27 @@ func TestParseHTML(t *testing.T) {
assert.Equal(t, "form1", v.Export())
}
})
t.Run("FromElement", func(t *testing.T) {
t.Parallel()
rt := getTestRuntimeWithDoc(t, testHTML)

_, err := rt.RunString(`var body = doc.find("body").get(0)`)
assert.NoError(t, err)

v, err := rt.RunString(`doc.fromElement(body).find('#top').text()`)
if assert.NoError(t, err) {
assert.Equal(t, "Lorem ipsum", v.String())
}
})
t.Run("Locator", func(t *testing.T) {
t.Parallel()
rt := getTestRuntimeWithDoc(t, testHTML)

v, err := rt.RunString(`doc.locator("#top").text()`)
if assert.NoError(t, err) {
assert.Equal(t, "Lorem ipsum", v.String())
}
})
t.Run("Contents", func(t *testing.T) {
t.Parallel()
rt := getTestRuntimeWithDoc(t, testHTML)
Expand Down

0 comments on commit 50d21c8

Please sign in to comment.