61

I have a WebElement, I want to reset its an attribute's value to some other value (for e.g. attr is the attribute, and I want to change its original value=1 to new value=10).

Is it possible? I am using Selenium 2.0 (WebDriver.)

Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
yami
  • 871
  • 1
  • 9
  • 14

7 Answers7

65

You would have to use the JavascriptExecutor class:

WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('//id of element').setAttribute('attr', '10')");
CBRRacer
  • 4,649
  • 1
  • 23
  • 27
  • 2
    Hi, Thanks for the reply but in Sel2.0 we can't get the document object reference. We have to get the element through WebDriver and it returns "WebElement" that doesn't support setting of attribute. driver.findElement(By.id("id of element')) – yami Dec 14 '11 at 08:18
  • @yami in Selenium 2 you can execute javascript which does support the access to the DOM. Just like running the same code on the website. You just don't use the WebElement class instead you JavascriptExecutor class and cast it with the WebDriver. – CBRRacer Dec 14 '11 at 14:08
  • 1
    That's right. I verified again and we can get the complete DOM reference and operate on it. However, once we pass JS script as string to executeScript then debugging gets tough.. Although i felt if it could have been through WebElement and it should have provided us the complete capability of DOM then it would have been great. But any how this answer helped me a lot..:-)and As of now i am ok with it. Thank you..!! – yami Dec 15 '11 at 08:22
  • 2
    Quickquestion: Is there a way to execute javascript in the context of a webelement? In other words: Having a `WebElement` (eg.: a simple `` with no other attributes) is there a way to execute javascript and somehow pass a reference to this js element. (maybe `this` in js would refer to it?) – Matyas Mar 26 '13 at 18:34
  • 3
    Found answer: pass `WebElement(s)` to executor and in script access `arguments[0]([1,2...])`. – Matyas Mar 26 '13 at 18:47
28

If you're using the PageFactory pattern or already have a reference to your WebElement, then you probably want to set the attribute, using your existing reference to the WebElement. (Rather than doing a document.getElementById(...) in your javascript)

The following sample allows you to set the attribute, using your existing WebElement reference.

Code Snippet

import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;

public class QuickTest {

    RemoteWebDriver driver;

    @FindBy(id = "foo")
    private WebElement username;

    public void exampleUsage(RemoteWebDriver driver) {
        setAttribute(username, "attr", "10");
        setAttribute(username, "value", "bar");
    }

    public void setAttribute(WebElement element, String attName, String attValue) {
        driver.executeScript("arguments[0].setAttribute(arguments[1], arguments[2]);", 
                element, attName, attValue);
    }
}
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • I use this approach. It success on firefox v30 and google chrome and IE, but failed on firefox v35, it said that arguments[0] is undefined, although I've waited this element until exists. – iroel Jan 19 '15 at 10:35
  • How is the performance of using this method multiple times versus executing a single script that sets all the needed attributes? Is there a lot of overhead in the executeScript method? – mrog May 08 '17 at 18:11
  • @mrog, I have no metrics on performance... (this was ~3 years ago). Also, what are you comparing it to? It takes a var arg array of arguments, so if you wanted "one" call, you could set multiple attributes at the same time... e.g. `driver.executeScript("arguments[0].setAttribute(arguments[1], arguments[2]);arguments[0].setAttribute(arguments[3], arguments[4]);", element, att1Name, att1Value, att2Name, att2Value);` – Nick Grealy May 08 '17 at 23:57
14

Fancy C# extension method based on previous answers:

public static IWebElement SetAttribute(this IWebElement element, string name, string value)
{
    var driver = ((IWrapsDriver)element).WrappedDriver;
    var jsExecutor = (IJavaScriptExecutor)driver;
    jsExecutor.ExecuteScript("arguments[0].setAttribute(arguments[1], arguments[2]);", element, name, value);

    return element;
}

Usage:

driver.FindElement(By.Id("some_option")).SetAttribute("selected", "selected");
Vitaliy Ulantikov
  • 10,157
  • 3
  • 61
  • 54
8

Another to answer this question available here answered by @nilesh https://stackoverflow.com/a/19934852/2079692

public void setAttributeValue(WebElement elem, String value){
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("arguments[0].setAttribute(arguments[1],arguments[2])",
        elem, "value", value
    );
}

this takes advantage of selenium findElementBy function where xpath can be used also.

frzsombor
  • 2,274
  • 1
  • 22
  • 40
Anudeep Samaiya
  • 1,910
  • 2
  • 28
  • 33
  • 1
    IMO "value" is a property rather than attribute. `'(arguments[0])[arguments[1]] = arguments[2]'` will work for `value`. – kenjiuno Apr 22 '19 at 03:50
0

I have created this jquery that solved my problem.

public void ChangeClassIntoSelected(String name,String div) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("Array.from($(\"div." + div +" ul[name=" + name + "]\")[0].children).forEach((element, index) => {\n" +
                "   $(element).addClass('ui-selected');\n" +
                "});");
    }

With this script you are able to change the actual class name into some other thing.

Katya Willard
  • 2,152
  • 4
  • 22
  • 43
0

I have posted a similar solution for the same problem,

visit How to use javascript to set attribute of selected web element using selenium Webdriver using java?

Here First we have find the element in my case I have found the element using xpath then we have traverse through the list of elements and then We have cast the driver object to the Executor object and create a script here the first argument is the element and second argument is the property and the third argument is the new value

List<WebElement> unselectableDiv = driver
                .findElements(By.xpath("//div[@class='x-grid3-cell-inner x-grid3-col-6']"));

        for (WebElement element : unselectableDiv) {

            // System.out.println( "**** Checking the size of div "+unselectableDiv.size());

            JavascriptExecutor js = (JavascriptExecutor) driver;

            String scriptSetAttr = "arguments[0].setAttribute(arguments[1],arguments[2])";

            js.executeScript(scriptSetAttr, element, "unselectable", "off");

            System.out.println(" *****   check value of Div property " + element.getAttribute("unselectable"));

        }
Sandeep Negi
  • 27
  • 1
  • 11
-2
    JavascriptExecutor js = (JavascriptExecutor) driver;        
    js.executeScript("document.getElementsByClassName('featured-heading')[0].setAttribute('style', 'background-color: green')");

I could add an attribute using the above code in java