Index: cms/converters.py
===================================================================
--- a/cms/converters.py
+++ b/cms/converters.py
@@ -469,20 +469,16 @@
                                                               _format)
             page_data = utils.extract_page_metadata(data)[0]
             page_data.setdefault('page', page_name)
             if self.filter_metadata(filters, page_data) is True:
                 return_data.append(page_data)
         return return_data
 
     def filter_metadata(self, filters, metadata):
-        # if only the page key is in the metadata then there
-        # was no user defined metadata
-        if metadata.keys() == ['page']:
-            return False
         if filters is None:
             return True
         for filter_name, filter_value in filters.items():
             if filter_name not in metadata:
                 return False
             if isinstance(metadata[filter_name], list):
                 if isinstance(filter_value, basestring):
                     filter_value = [filter_value]
Index: tests/expected_output/en/sitemap
===================================================================
--- a/tests/expected_output/en/sitemap
+++ b/tests/expected_output/en/sitemap
@@ -1,19 +1,29 @@
 
 
 
 <h1> Unfiltered </h1>
 <ul>
+  <li>title : bar </li>
+  <li>title : filter </li>
+  <li>title : get_page_url </li>
+  <li>title : global </li>
   <li>title : includer </li>
   <li>title : metadata_json </li>
   <li>title : metadata_json_comment </li>
   <li>title : metadata_old_comment </li>
   <li>title : sitemap </li>
+  <li>title : translate </li>
+  <li>title : translate-html </li>
+  <li>title : translate-include </li>
+  <li>title : translate-not-enough </li>
+  <li>title : translate-partial </li>
   <li>title : translate-template </li>
+  <li>title : translate-tmpl </li>
 </ul>
 
 <h1> Filtered </h1>
 <ul><li>title : sitemap </li>
 </ul>
 
 <h1> String Filter For Listy Option </h1>
 <ul><li>title : sitemap </li>
Index: tests/expected_output/en/sitemap@static+master
===================================================================
new file mode 100644
--- /dev/null
+++ b/tests/expected_output/en/sitemap@static+master
@@ -0,0 +1,29 @@
+
+
+
+<h1> Unfiltered </h1>
+<ul>
+  <li>title : filter </li>
+  <li>title : get_page_url </li>
+  <li>title : global </li>
+  <li>title : includer </li>
+  <li>title : metadata_json </li>
+  <li>title : metadata_json_comment </li>
+  <li>title : metadata_old_comment </li>
+  <li>title : sitemap </li>
+  <li>title : translate </li>
+  <li>title : translate-html </li>
+  <li>title : translate-include </li>
+  <li>title : translate-not-enough </li>
+  <li>title : translate-partial </li>
+  <li>title : translate-template </li>
+  <li>title : translate-tmpl </li>
+</ul>
+
+<h1> Filtered </h1>
+<ul><li>title : sitemap </li>
+</ul>
+
+<h1> String Filter For Listy Option </h1>
+<ul><li>title : sitemap </li>
+</ul>
Index: tests/test_page_outputs.py
===================================================================
--- a/tests/test_page_outputs.py
+++ b/tests/test_page_outputs.py
@@ -8,20 +8,29 @@
 from .utils import get_dir_contents, run_test_server
 
 
 def get_expected_outputs(test_type):
     expected_out_path = os.path.join(ROOTPATH, 'tests', 'expected_output')
     outputs = get_dir_contents(expected_out_path)
     for filename in list(outputs):
         # Move test-type-specific expected outputs (e.g. "xyz@static" -> "xyz")
-        # and remove the expected outputs that don't apply for this test type.
+        # There are cases where we need to test outputs which differ depending
+        # on how they are generated; either statically or dynamically
         if filename.endswith('@' + test_type):
             realname = filename.split('@')[0]
             outputs[realname] = outputs[filename]
+        # Move bookmark specific output (e.g. "xyx@static+master -> xyz+master)
+        # There are cases where we need to test outputs which differ depending
+        # on the bookmark which they are generated from:
+        # https://issues.adblockplus.org/ticket/6605
+        if '+' in filename:
+            realname = ''.join(filename.split('@' + test_type))
+            outputs[realname] = outputs[filename]
+        # Remove the expected outputs that don't apply for this test type.
         if '@' in filename:
             del outputs[filename]
     return outputs.items()
 
 
 static_expected_outputs = get_expected_outputs('static')
 dynamic_expected_outputs = get_expected_outputs('dynamic')
 
@@ -49,20 +58,23 @@
 
 
 @pytest.fixture(scope='session')
 def output_pages(static_output):
     return get_dir_contents(static_output)
 
 
 @pytest.mark.parametrize('filename,expected_output', static_expected_outputs)
-def test_static(output_pages, filename, expected_output):
+def test_static(revision, output_pages, filename, expected_output):
     if expected_output.startswith('## MISSING'):
         assert filename not in output_pages
-    else:
+    elif revision and '+' + revision in filename:
+        filename = filename.split('+')[0]
+        assert expected_output == output_pages[filename]
+    elif not revision and '+' not in filename:
         assert expected_output == output_pages[filename]
 
 
 @pytest.mark.parametrize('filename,expected_output', dynamic_expected_outputs)
 def test_dynamic(dynamic_server, filename, expected_output):
     response = urllib2.urlopen(dynamic_server + filename)
     assert expected_output == response.read().strip()
 
