@@ -44,6 +44,7 @@ import org.apache.spark.internal.config.Status._
4444import org .apache .spark .internal .config .UI ._
4545import org .apache .spark .shuffle .FetchFailedException
4646import org .apache .spark .status .api .v1 .{JacksonMessageWriter , RDDDataDistribution , StageStatus }
47+ import org .apache .spark .util .CallSite
4748
4849private [spark] class SparkUICssErrorHandler extends DefaultCssErrorHandler {
4950
@@ -772,6 +773,33 @@ class UISeleniumSuite extends SparkFunSuite with WebBrowser with Matchers with B
772773 }
773774 }
774775
776+ test(" SPARK-31534: text for tooltip should be escaped" ) {
777+ withSpark(newSparkContext()) { sc =>
778+ sc.setLocalProperty(CallSite .LONG_FORM , " collect at <console>:25" )
779+ sc.setLocalProperty(CallSite .SHORT_FORM , " collect at <console>:25" )
780+ sc.parallelize(1 to 10 ).collect
781+
782+ val driver = webDriver.asInstanceOf [HtmlUnitDriver ]
783+ driver.setJavascriptEnabled(true )
784+
785+ eventually(timeout(10 .seconds), interval(50 .milliseconds)) {
786+ goToUi(sc, " /jobs" )
787+ val jobDesc =
788+ driver.findElement(By .cssSelector(" div[class='application-timeline-content']" ))
789+ jobDesc.getAttribute(" data-title" ) should include (" collect at <console>:25" )
790+
791+ goToUi(sc, " /jobs/job/?id=0" )
792+ val stageDesc = driver.findElement(By .cssSelector(" div[class='job-timeline-content']" ))
793+ stageDesc.getAttribute(" data-title" ) should include (" collect at <console>:25" )
794+
795+ // Open DAG Viz.
796+ driver.findElement(By .id(" job-dag-viz" )).click()
797+ val nodeDesc = driver.findElement(By .cssSelector(" g[class='node_0 node']" ))
798+ nodeDesc.getAttribute(" name" ) should include (" collect at <console>:25" )
799+ }
800+ }
801+ }
802+
775803 def goToUi (sc : SparkContext , path : String ): Unit = {
776804 goToUi(sc.ui.get, path)
777805 }
0 commit comments