@@ -183,7 +183,10 @@ def is_link_text_present(self, link_text):
183
183
return True
184
184
return False
185
185
186
- def get_link_text_attribute (self , link_text , attribute ):
186
+ def get_link_attribute (self , link_text , attribute , hard_fail = True ):
187
+ """ Finds a link by link text and then returns the attribute's value.
188
+ If the link text or attribute cannot be found, an exception will
189
+ get raised if hard_fail is True (otherwise None is returned). """
187
190
self .wait_for_ready_state_complete ()
188
191
source = self .get_page_source ()
189
192
soup = BeautifulSoup (source , "html.parser" )
@@ -193,9 +196,16 @@ def get_link_text_attribute(self, link_text, attribute):
193
196
if html_link .has_attr (attribute ):
194
197
attribute_value = html_link .get (attribute )
195
198
return attribute_value
196
- raise Exception (
197
- 'Could not parse link from link_text [%s]' % link_text )
198
- raise Exception ("Link Text [%s] was not found!" % link_text )
199
+ if hard_fail :
200
+ raise Exception (
201
+ 'Unable to find attribute [%s] from link text [%s]!'
202
+ % (attribute , link_text ))
203
+ else :
204
+ return None
205
+ if hard_fail :
206
+ raise Exception ("Link text [%s] was not found!" % link_text )
207
+ else :
208
+ return None
199
209
200
210
def wait_for_link_text_present (self , link_text ,
201
211
timeout = settings .SMALL_TIMEOUT ):
@@ -243,33 +253,46 @@ def click_link_text(self, link_text, timeout=settings.SMALL_TIMEOUT):
243
253
link_text , timeout = timeout )
244
254
element .click ()
245
255
except Exception :
246
- hidden_css = None
247
- try :
248
- href = self ._get_href_from_link_text (link_text )
249
- link_css = '[href="%s"]' % href
256
+ found_css = False
257
+ text_id = self .get_link_attribute (link_text , "id" , False )
258
+ if text_id :
259
+ link_css = '[id="%s"]' % link_text
260
+ found_css = True
261
+
262
+ if not found_css :
263
+ href = self ._get_href_from_link_text (link_text , False )
264
+ if href :
265
+ if href .startswith ('/' ) or page_utils .is_valid_url (href ):
266
+ link_css = '[href="%s"]' % href
267
+ found_css = True
268
+
269
+ if not found_css :
270
+ ngclick = self .get_link_attribute (link_text , "ng-click" , False )
271
+ if ngclick :
272
+ link_css = '[ng-click="%s"]' % ngclick
273
+ found_css = True
274
+
275
+ if not found_css :
276
+ onclick = self .get_link_attribute (link_text , "onclick" , False )
277
+ if onclick :
278
+ link_css = '[onclick="%s"]' % onclick
279
+ found_css = True
280
+
281
+ success = False
282
+ if found_css :
250
283
if self .is_element_visible (link_css ):
251
284
self .click (link_css )
285
+ success = True
252
286
else :
253
- hidden_css = link_css
254
- raise Exception ("Element %s is not clickable!" % link_css )
255
- except Exception :
256
- try :
257
- ng_click = self ._get_ng_click_from_link_text (link_text )
258
- link_css = '[ng-click="%s"]' % (ng_click )
259
- if self .is_element_visible (link_css ):
260
- self .click (link_css )
261
- else :
262
- if not hidden_css :
263
- hidden_css = link_css
264
- raise Exception (
265
- "Element %s is not clickable!" % link_css )
266
- except Exception :
267
- # The link text is probably hidden under a dropdown menu
268
- if not self ._click_dropdown_link_text (link_text ,
269
- hidden_css ):
270
- element = self .wait_for_link_text_visible (
271
- link_text , timeout = settings .MINI_TIMEOUT )
272
- element .click ()
287
+ # The link text might be hidden under a dropdown menu
288
+ success = self ._click_dropdown_link_text (
289
+ link_text , link_css )
290
+
291
+ if not success :
292
+ element = self .wait_for_link_text_visible (
293
+ link_text , timeout = settings .MINI_TIMEOUT )
294
+ element .click ()
295
+
273
296
if settings .WAIT_FOR_RSC_ON_CLICKS :
274
297
self .wait_for_ready_state_complete ()
275
298
if self .demo_mode :
@@ -1513,8 +1536,10 @@ def process_checks(self, print_only=False):
1513
1536
1514
1537
############
1515
1538
1516
- def _get_href_from_link_text (self , link_text ):
1517
- href = self .get_link_text_attribute (link_text , "href" )
1539
+ def _get_href_from_link_text (self , link_text , hard_fail = True ):
1540
+ href = self .get_link_attribute (link_text , "href" , hard_fail )
1541
+ if not href :
1542
+ return None
1518
1543
if href .startswith ('//' ):
1519
1544
link = "http:" + href
1520
1545
elif href .startswith ('/' ):
@@ -1525,16 +1550,12 @@ def _get_href_from_link_text(self, link_text):
1525
1550
link = href
1526
1551
return link
1527
1552
1528
- def _get_ng_click_from_link_text (self , link_text ):
1529
- ng_click = self .get_link_text_attribute (link_text , "ng-click" )
1530
- return ng_click
1531
-
1532
- def _click_dropdown_link_text (self , link_text , hidden_css ):
1533
- """ When a link is hidden under a dropdown menu, use this. """
1553
+ def _click_dropdown_link_text (self , link_text , link_css ):
1554
+ """ When a link may be hidden under a dropdown menu, use this. """
1534
1555
source = self .get_page_source ()
1535
1556
soup = BeautifulSoup (source , "html.parser" )
1536
1557
drop_down_list = soup .select ('[class*=dropdown]' )
1537
- csstype = hidden_css .split ('[' )[1 ].split ('=' )[0 ]
1558
+ csstype = link_css .split ('[' )[1 ].split ('=' )[0 ]
1538
1559
for item in drop_down_list :
1539
1560
if link_text in item .text .split ('\n ' ) and csstype in item .decode ():
1540
1561
dropdown_css = ""
@@ -1547,8 +1568,8 @@ def _click_dropdown_link_text(self, link_text, hidden_css):
1547
1568
# The same class names might be used for multiple dropdowns
1548
1569
try :
1549
1570
page_actions .hover_element_and_click (
1550
- self .driver , dropdown , hidden_css ,
1551
- click_by = By .CSS_SELECTOR , timeout = 0.2 )
1571
+ self .driver , dropdown , link_text ,
1572
+ click_by = By .LINK_TEXT , timeout = 0.1 )
1552
1573
return True
1553
1574
except Exception :
1554
1575
pass
0 commit comments