ExLibris enforces selection of Circulation Desk - breaks Configuration Menu
For our instances, after logging in, staff have to manually select the circulation desk they're using for that session. (independently of their actual workplace):

Until recently, it didn't have any adverse effect on configuration in general if that step was skipped - especially the configuration menu didn't really require selecting the (uneccessary, in that context) circulation desk and worked "anyway".
A user logging in manually is hindered by the pop-up to select the underlying elements of the Alma home screen and has to select a circulation desk. Selenium however happily ignores the intrusive pop-up and proceeds anyway.
As of lately in both Production and Sandbox, this benign behaviour of Alma is no longer the case. If there is no circulation desk selected, the configuration menu is displayed empty:

Slipsomat -which now would rather proceed directly to the configuration menu- gets rather unhappy about this, and bails.
Starting slipsomat 0.2.4
Connecting to sandbox02-eu:49KOBV_HUB
Logging in as ... DONE
Reading table... Traceback (most recent call last):
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 226, in open
self.worker.first(By.CSS_SELECTOR, '#TABLE_DATA_fileList')
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/worker.py", line 43, in first
return self.driver.find_element(by, by_value)
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 957, in find_element
'value': value})['value']
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 314, in execute
self.error_handler.check_response(response)
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: #TABLE_DATA_fileList
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/bin/slipsomat", line 11, in <module>
sys.exit(main())
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/shell.py", line 196, in main
shell = Shell()
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/shell.py", line 54, in __init__
self.table = TemplateConfigurationTable(self.worker)
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 221, in __init__
self.open()
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 234, in open
self.worker.click(By.XPATH, '//*[@href="#CONF_MENU6"]')
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/worker.py", line 63, in click
element = self.wait.until(EC.element_to_be_clickable((by, by_value)))
File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Following the new python/selenium for beginners mini-tutorial (and a big thanks for that help!)
I got it to stop at the selection screen after worker.connect().
Would it be possible to add either a default circulation desk to slipsomat.cfg, or use the first element of the history as default?
<div class="marSidesAuto panel panel-default section "><div id="FORM_LABEL_idCollapseTagUXP_924" class="panel-heading jsHideInIframePopup marbottom5"><div class="panel-title"><div class="entityAudit alignRight"></div><a title="" class="btn btn-secondary border0 collapsible" role="button" data-toggle="collapse" href="#idCollapseTagUXP_924" aria-controls="idCollapseTagUXP_924" aria-expanded="true"><span class="alignRight glyphicon glyphicon-menu-right"></span><span class="sectionTitle">Please choose your current desk/department</span></a></div></div><div id="idCollapseTagUXP_924" class="panel-collapse collapse in" role="tabpanel"><div class="panel-body"><!-- ERRORS -->
<script>
function selectInstitution(newInst) {//open link in same window or differnt tab/window based on customer parameter
var condition="";
if(condition=="window"){
var features = "width="+$(window).width()+",height="+ $(window).height()+",menubar=1, toolbar=1";
window.open(newInst, "window2", features);
}else if(condition=="tab"){
window.open(newInst);
}else{
location.href=newInst;
}
}
function changeInstitutionFromSelect(){
selectInstitution($('#pageBeanselectedInst').val());
}
</script>
<div id="availableUnits" class="">
<div class="form row"><div class="col col-md-12 col-xs-12 wide-field-1 marbottom5 ">
<div class="row ">
<label class="col col-md-3 col-xs-2 control-label height34 displayTable lineHeight35 padSides5 fontReg textRight" for="pageBeanselectedLocation"><span class="displayTableCell verticalMiddle lineHeight16">I am physically at:</span><span class="dummySpace"> </span></label>
<div class="col col-md-8 col-xs-10 form-field leftMarginA">
<div class="input-group ui-combobox"><input id="pageBeanselectedLocation" class="form-control ui-combobox-input ui-autocomplete-input ui-widget ui-widget-content jsComboPlaceholder defaultPlaceholderDiv jsRemoveOnInit jsLazyInit" value="None of these"><span class="input-group-btn jsRemoveOnInit "><button aria-label="Option list toggle" type="button" class="jsLazyInit btn btn-secondary dropdown-toggle height34 jsComboPlaceholder defaultPlaceholderButton"><span class="caret"></span></button></span><select data-save-sh="true" name="pageBean.selectedLocation" id="pageBeanselectedLocation_hiddenSelect" class="jsDummy jsCombobox jsAddHideClass " title="Select an item from the list. Use autocomplete to view fewer options. Press ESC to reset." >
<option class=" jsKeepBottom " value="Null" >None of these</option>
<option value="121" >Digitization Department For Institution</option>
<option value="1713420350002882" >long list edited short</option>
<option value="395021420002882" >sublibrary-cd-xxx</option>
<option value="1713420410002882" >sublibrary-cd-xxx</option>
<option class="selectionHistoryItem" value="395017700002882" >sublibrary-cd-xxx</option>
<option class="selectionHistoryItem" value="1713419540002882" >sublibrary-cd-xxx</option>
</select>
</div><div id="pageBeanselectedLocation_invalid_error" class=" hide alert alert-danger jsToolTip ">The phrase didn't match any value.</div></div>
</div>
</div>
</div>
I tried to select one of the circulation desks:
find_element_by_xpath("//select[@id='pageBeanselectedLocation']/option[@value='395017700002882']").click()
but my hybris was promptly regarded with a number of errors I'm currently trying to learn my way out of.
Interesting, we haven't got that for our instance (luckily).
Glad the tutorial helped!
Yes, we can make it an optional item in the config file. If you manage to find out which steps are needed to proceed using your static value ('395017700002882'), I can modify it to read the value from the configuration file instead.
If the selection itself didn't work, you could try the Select helper – something like this (not tested!):
from selenium.webdriver.support.ui import Select
element = find_element_by_xpath("//select[@id='pageBeanselectedLocation']")
select = Select(element)
select.select_by_value('395017700002882')
Thanks for the idea - I'm unfortunately still struggling at the find_element_by_xpath which I seem to be calling wrong, no matter how I'm trying to work around that. It all starts with
NameError: name 'find_element_by_xpath' is not defined
and gets consecutively worse as I experiment around that >)
Ah, didn't notice that. It's because find_element_by_xpath is defined on the driver, more specifically on worker.driver, so I think this should work:
element = worker.driver.find_element_by_xpath("//select[@id='pageBeanselectedLocation']")
If that works, you can check if this also does:
wait = worker.waiter()
element = wait.until(EC.element_to_be_clickable((By.XPATH, '//select[@id='pageBeanselectedLocation']')))
This effectively does the same, but will wait rather than crash if the element has not yet loaded.
I had tried driver.find... to no avail, worker.driver it was, thanks!
Looking (almost :) good with a few corrections, but the select seems to need a two stage process, first to get the item to display, then it can be selected?
The select bails with a selenium.common.exceptions.ElementNotInteractableException: Message: Element <option> could not be scrolled into view, unless I previously (manually, will try to automate that on friday) activate the list so it pops open, displaying the item to select:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from slipsomat.worker import Worker
from slipsomat.slipsomat import TemplateConfigurationTable
from selenium.webdriver.support.ui import Select
worker = Worker('slipsomat.cfg')
worker.connect()
element = worker.driver.find_element_by_xpath("//select[@id='pageBeanselectedLocation_hiddenSelect']")
select = Select(element)
select.select_by_value('3709875230002882')
Yes, you have to ask Selenium to wait selecting until it's clickable. Usually, but not always, something like this works:
wait = worker.waiter()
element = wait.until(EC.element_to_be_clickable((By.XPATH, '//select[@id='pageBeanselectedLocation_hiddenSelect']')))