Home > other >  Submit type button with dynamic attribute - Selenium
Submit type button with dynamic attribute - Selenium

Time:09-18

I want to submit type button, send a POST Request with JS addLevel() and show dialogbox form like bellow

<button type="button" keyid="11" lvl="80" group="4" onclick="addLevel(this)"><span ></span> Add Level</button>



function addLevel(obj) {
$("#modalFormAdd").modal();
$("#modal-body").addClass("loading");
$("#modal-body").html("");
$.post("level/form_add",{lvl:$(obj).attr("lvl"),keyid:$(obj).attr("keyid"),groupid:$(obj).attr("groupid")},function(data){
    $("#modal-body").html(data);
    $("#modal-body").removeClass("loading");
});
}

With Selenium, I want to loop and change parameters value (keyid="11" lvl="80" group="4") at submit button with variables (keyid, lvl, group) from array data, but still having problems in change attribute with variables in looping

this Selenium code:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('URL')

key_id = [11, 12, 13, 14, 15, 16]
level_id = [80, 81, 80, 81, 82, 81]
group_id = [4, 3, 4, 4, 1, 2]

# ===>  looping from array above
for i in range(0, len(key_id)):
    keyid = key_id[i]
    lvl = level_id[i]
    group = group_id[i]

    # I Expected code below to change parameters value with variable above when looping
    submit = driver.find_element(
        By.XPATH, '//*[@id="tabelData"]/tbody/tr[1]/td[2]/div[2]/button')
    driver.execute_script("arguments[0].click();", submit)

I expected this HTML button when click/submit when looping with Selenium

<button type="button" keyid="11" lvl="80" group="4" onclick="addLevel(this)"><span ></span> Add Level</button>
<button type="button" keyid="12" lvl="81" group="3" onclick="addLevel(this)"><span ></span> Add Level</button>
<button type="button" keyid="13" lvl="80" group="4" onclick="addLevel(this)"><span ></span> Add Level</button>
<button type="button" keyid="14" lvl="81" group="4" onclick="addLevel(this)"><span ></span> Add Level</button>
<button type="button" keyid="15" lvl="82" group="1" onclick="addLevel(this)"><span ></span> Add Level</button>
<button type="button" keyid="16" lvl="83" group="2" onclick="addLevel(this)"><span ></span> Add Level</button>

CodePudding user response:

You can use JavaScript to set attribute

k = 11
driver.execute_script(f"arguments[0].setAttribute('keyid', '{k}')", submit)

or even more universal

def set_attribute(driver, widget, name, value):
    #driver.execute_script(f"arguments[0].setAttribute('{name}', '{val}')", widget)
    driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", widget, name, value)

set_attribute(driver, submit, 'keyid', 11)
set_attribute(driver, submit, 'lvl', 80)
set_attribute(driver, submit, 'group', 4)

I test it on minimal working example:

My function addLevel() only gets values from button and displays them in console.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

#from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager

# ---

def set_attribute(driver, widget, name, value):
    #driver.execute_script(f"arguments[0].setAttribute('{name}', '{val}')", widget)
    driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", widget, name, value)
    
# ---

#driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()))

html = '''
<!DOCTYEP html>
<body>
<script>
function addLevel(obj) {
    k = obj.getAttribute('keyid');
    l = obj.getAttribute('lvl');
    g = obj.getAttribute('group');
    console.log('k,l,g: '   k   ','   l   ','   g   ',');
}
</script>
<form action="https://httpbin.org/post" method="POST">
<button type="button" keyid="0" lvl="0" group="0" onclick="addLevel(this)">Add Level</button>
</form>
</body>
</html>
'''

driver.get("data:text/html;charset=utf-8,"   html)

key_id = [11, 12, 13, 14, 15, 16]
level_id = [80, 81, 80, 81, 82, 81]
group_id = [4, 3, 4, 4, 1, 2]

for k, l, g in zip(key_id, level_id, group_id):
    submit = driver.find_element(By.XPATH, '//button')
    
    #driver.execute_script(f"arguments[0].setAttribute('keyid', '{k}')", submit)
    #driver.execute_script(f"arguments[0].setAttribute('lvl', '{l}')", submit)
    #driver.execute_script(f"arguments[0].setAttribute('group', '{g}')", submit)
    
    set_attribute(driver, submit, 'keyid', k)
    set_attribute(driver, submit, 'lvl', l)
    set_attribute(driver, submit, 'group', g)
    print('k,l,g:', submit.get_attribute('keyid'), submit.get_attribute('lvl'), submit.get_attribute('group'))
    
    driver.execute_script("arguments[0].click();", submit)
  • Related