Index: trunk/src/org/openstreetmap/josm/data/validation/Test.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 15971)
+++ trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 15972)
@@ -382,3 +382,11 @@
         showElementCount = b;
     }
+
+    /**
+     * @return the name of this class (for ToolTip)
+     * since 15972
+     */
+    public Object getSource() {
+        return "Java: " + this.getClass().getName();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 15971)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 15972)
@@ -107,4 +107,15 @@
         /** MapCSS declaration **/
         public final Declaration declaration;
+        /** MapCSS source **/
+        public final String source;
+
+        /**
+         * Constructs a new {@code GroupedMapCSSRule} with empty source
+         * @param selectors MapCSS selectors
+         * @param declaration MapCSS declaration
+         */
+        public GroupedMapCSSRule(List<Selector> selectors, Declaration declaration) {
+            this(selectors, declaration, "");
+        }
 
         /**
@@ -112,8 +123,10 @@
          * @param selectors MapCSS selectors
          * @param declaration MapCSS declaration
-         */
-        public GroupedMapCSSRule(List<Selector> selectors, Declaration declaration) {
+         * @param source the source of the rule
+         */
+        public GroupedMapCSSRule(List<Selector> selectors, Declaration declaration, String source) {
             this.selectors = selectors;
             this.declaration = declaration;
+            this.source = source;
         }
 
@@ -391,4 +404,8 @@
 
         static ParseResult readMapCSS(Reader css) throws ParseException {
+            return readMapCSS(css, "");
+        }
+
+        static ParseResult readMapCSS(Reader css, String url) throws ParseException {
             CheckParameterUtil.ensureParameterNotNull(css, "css");
 
@@ -415,5 +432,5 @@
                 try {
                     parseChecks.add(TagCheck.ofMapCSSRule(
-                            new GroupedMapCSSRule(map.getValue(), map.getKey())));
+                            new GroupedMapCSSRule(map.getValue(), map.getKey(), url)));
                 } catch (IllegalDataException e) {
                     Logging.error("Cannot add MapCss rule: "+e.getMessage());
@@ -707,4 +724,9 @@
             return "MapCSSTagCheckerAndRule [rule=" + rule + ']';
         }
+
+        @Override
+        public String getSource() {
+            return tr("URL / File: {0}", rule.source);
+        }
     }
 
@@ -849,5 +871,5 @@
             if (zip != null)
                 I18n.addTexts(cache.getFile());
-            result = TagCheck.readMapCSS(reader);
+            result = TagCheck.readMapCSS(reader, url);
             checks.remove(url);
             checks.putAll(url, result.parseChecks);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(revision 15971)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(revision 15972)
@@ -117,15 +117,21 @@
             if (nodeInfo instanceof TestError) {
                 TestError error = (TestError) nodeInfo;
-                res = "<html>" + error.getNameVisitor().getText() + "<br>" + error.getMessage();
+                res = error.getNameVisitor().getText() + "<br>" + error.getMessage();
                 String d = error.getDescription();
                 if (d != null)
                     res += "<br>" + d;
-                res += "<br>" + tr("Test: {0}", error.getTester().getName());
-                res += "</html>";
+                res += "<br>" + tr("Test: {0}", getTesterDetails(error));
             } else {
-                res = node.toString();
-            }
-        }
-        return res;
+                Set<String> tests = new HashSet<>();
+                visitTestErrors(node, err -> tests.add(getTesterDetails(err)), null);
+                String source = (tests.size() == 1) ? tr("Test: {0}", tests.iterator().next()) : tr("Different tests");
+                res = node.toString() + "<br>" + source;
+            }
+        }
+        return "<html>" + res + "</html>";
+    }
+
+    private static String getTesterDetails(TestError e) {
+        return e.getTester().getName() + "<br>" + e.getTester().getSource();
     }
 
