diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-14 15:00:14 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-14 15:00:14 +0530 |
commit | d28fb42201dd743c470fcc1f43bf2e13f1c8cddc (patch) | |
tree | ce424e2ca8a8f86e1a8a4a1b86804ec0093d4aa7 | |
parent | a76de4b0cc2ec1e37539e9d328c9825c9812be78 (diff) | |
parent | d8511c8b8d7dc9c73d42e9430a8aa0b608491599 (diff) | |
download | servo-d28fb42201dd743c470fcc1f43bf2e13f1c8cddc.tar.gz servo-d28fb42201dd743c470fcc1f43bf2e13f1c8cddc.zip |
Auto merge of #9293 - Ms2ger:reftests, r=SimonSapin
Remove the legacy reftest framework.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9293)
<!-- Reviewable:end -->
22 files changed, 228 insertions, 556 deletions
diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 875137ff536..9892a0e6669 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -201,52 +201,11 @@ class MachCommands(CommandBase): @Command('test-ref', description='Run the reference tests', category='testing') - @CommandArgument('--kind', '-k', default=DEFAULT_RENDER_MODE, - help=HELP_RENDER_MODE) - @CommandArgument('--release', '-r', action='store_true', - help='Run with a release build of Servo') - @CommandArgument('--include', default=None, nargs='+', - help="Only run tests that match this pattern. If the " - "path to the ref test directory is included, it " - "will automatically be trimmed out.") - @CommandArgument( - 'servo_params', default=None, nargs=argparse.REMAINDER, - help="Command-line arguments to be passed through to Servo") - def test_ref(self, kind=DEFAULT_RENDER_MODE, include=None, servo_params=None, - release=False): - self.ensure_bootstrapped() - self.ensure_built_tests(release=release) - assert kind is not None, 'kind cannot be None, see help' - - kinds = ["cpu", "gpu"] if kind == 'both' else [kind] - test_path = path.join(self.context.topdir, "tests", "ref") - error = False - - test_start = time() - for k in kinds: - print("Running %s reftests..." % k) - test_args = [k, test_path] - if include is not None: - ref_path = path.join("tests", "ref") - for name in include: - # Check to see if we were passed something leading with the - # path to the ref test directory, and trim it so that reftest - # knows how to filter it. - maybe_path = path.normpath(name) - if ref_path in maybe_path: - test_args.append(path.relpath(maybe_path, ref_path)) - else: - test_args.append(name) - if servo_params is not None: - test_args += ["--"] + servo_params - ret = self.run_test("reftest", test_args, release=release) - error = error or ret != 0 - elapsed = time() - test_start - - print("Reference tests completed in %0.2fs" % elapsed) - - if error: - return 1 + @CommandArgument('params', default=None, nargs=argparse.REMAINDER) + def test_ref(self, params=None): + print("Ref tests have been replaced by web-platform-tests under " + "tests/wpt/mozilla/.") + return 0 @Command('test-content', description='Run the content tests', diff --git a/python/tidy.py b/python/tidy.py index a3a7bf65ab9..10c07bde16a 100644 --- a/python/tidy.py +++ b/python/tidy.py @@ -19,8 +19,6 @@ import sys from licenseck import licenses filetypes_to_check = [".rs", ".rc", ".cpp", ".c", ".h", ".lock", ".py", ".toml", ".webidl"] -reftest_dir = "./tests/ref" -reftest_filetype = ".list" ignored_files = [ # Upstream @@ -62,10 +60,6 @@ def should_check(file_name): return True -def should_check_reftest(file_name): - return file_name.endswith(reftest_filetype) - - EMACS_HEADER = "/* -*- Mode:" VIM_HEADER = "/* vim:" MAX_LICENSE_LINESPAN = max(len(license.splitlines()) for license in licenses) @@ -517,44 +511,6 @@ def collect_errors_for_files(files_to_check, checking_functions, line_checking_f yield (filename,) + error -def check_reftest_order(files_to_check): - for file_name in files_to_check: - with open(file_name, "r") as fp: - split_lines = fp.read().splitlines() - lines = filter(lambda l: len(l) > 0 and l[0] != '#', split_lines) - for idx, line in enumerate(lines[:-1]): - next_line = lines[idx + 1] - current = get_reftest_names(line) - next = get_reftest_names(next_line) - if current is not None and next is not None and current > next: - yield (file_name, split_lines.index(next_line) + 1, "line not in alphabetical order") - - -def get_reftest_names(line): - tokens = line.split() - if len(tokens) == 3: - return tokens[1] + tokens[2] - if len(tokens) == 4: - return tokens[2] + tokens[3] - return None - - -def get_html_file_names_from_reftest_list(reftest_dir, file_name): - for line in open(os.path.join(reftest_dir, file_name), "r"): - for token in line.split(): - if fnmatch.fnmatch(token, '*.html'): - yield os.path.join(reftest_dir, token) - - -def check_reftest_html_files_in_basic_list(reftest_dir): - basic_list_files = set(get_html_file_names_from_reftest_list(reftest_dir, "basic" + reftest_filetype)) - - for file_name in os.listdir(reftest_dir): - file_path = os.path.join(reftest_dir, file_name) - if fnmatch.fnmatch(file_path, '*.html') and file_path not in basic_list_files: - yield (file_path, "", "not found in basic.list") - - def check_wpt_lint_errors(): wpt_working_dir = os.path.abspath(os.path.join(".", "tests", "wpt", "web-platform-tests")) site.addsitedir(wpt_working_dir) @@ -586,11 +542,6 @@ def scan(faster=False): line_checking_functions = (check_license, check_by_line, check_toml, check_rust, check_spec) errors = collect_errors_for_files(files_to_check, checking_functions, line_checking_functions) - # reftest checks - reftest_to_check = filter(should_check_reftest, get_file_list(reftest_dir, faster)) - r_errors = check_reftest_order(reftest_to_check) - not_found_in_basic_list_errors = check_reftest_html_files_in_basic_list(reftest_dir) - # wpt lint checks if faster: print "\033[93mUsing test-tidy \033[01m--faster\033[22m, skipping WPT lint\033[0m" @@ -599,7 +550,7 @@ def scan(faster=False): wpt_lint_errors = check_wpt_lint_errors() # collect errors - errors = itertools.chain(errors, r_errors, not_found_in_basic_list_errors, wpt_lint_errors) + errors = itertools.chain(errors, wpt_lint_errors) error = None for error in errors: diff --git a/tests/ref/100x100_green.png b/tests/ref/100x100_green.png Binary files differdeleted file mode 100644 index b23bbba154e..00000000000 --- a/tests/ref/100x100_green.png +++ /dev/null diff --git a/tests/ref/2x4.png b/tests/ref/2x4.png Binary files differdeleted file mode 100644 index 7efc762459b..00000000000 --- a/tests/ref/2x4.png +++ /dev/null diff --git a/tests/ref/basic.list b/tests/ref/basic.list deleted file mode 100644 index 4ee563b6c09..00000000000 --- a/tests/ref/basic.list +++ /dev/null @@ -1,8 +0,0 @@ -# This file must be sorted alphabetically. -# Please run `./mach test-tidy` to check your changes. - -# Should be == with expected failure: -fragment=top != ../html/acid2.html acid2_ref.html - -# This file must be sorted alphabetically. -# Please run `./mach test-tidy` to check your changes. diff --git a/tests/ref/css/ahem.css b/tests/ref/css/ahem.css deleted file mode 100644 index 51eede74aaa..00000000000 --- a/tests/ref/css/ahem.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - font-family: 'ahem'; - font-size: 100px; - line-height: 1; -} diff --git a/tests/ref/css/displaynone.css b/tests/ref/css/displaynone.css deleted file mode 100644 index 525534e8ff4..00000000000 --- a/tests/ref/css/displaynone.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - display: none; -} - diff --git a/tests/ref/png_rgba_colorspace_a.png b/tests/ref/png_rgba_colorspace_a.png Binary files differdeleted file mode 100644 index 9b9bd17fe47..00000000000 --- a/tests/ref/png_rgba_colorspace_a.png +++ /dev/null diff --git a/tests/ref/reset.css b/tests/ref/reset.css deleted file mode 100644 index e5156472701..00000000000 --- a/tests/ref/reset.css +++ /dev/null @@ -1,48 +0,0 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/tests/ref/rippy.jpg b/tests/ref/rippy.jpg Binary files differdeleted file mode 100644 index 2a1e0dc9e4c..00000000000 --- a/tests/ref/rippy.jpg +++ /dev/null diff --git a/tests/ref/rust-0.png b/tests/ref/rust-0.png Binary files differdeleted file mode 100644 index 20d93badf5e..00000000000 --- a/tests/ref/rust-0.png +++ /dev/null diff --git a/tests/ref/rust.png b/tests/ref/rust.png Binary files differdeleted file mode 100644 index 68b5ed31e7b..00000000000 --- a/tests/ref/rust.png +++ /dev/null diff --git a/tests/ref/rust_logo.png b/tests/ref/rust_logo.png Binary files differdeleted file mode 100644 index 20d93badf5e..00000000000 --- a/tests/ref/rust_logo.png +++ /dev/null diff --git a/tests/ref/test.jpeg b/tests/ref/test.jpeg Binary files differdeleted file mode 100644 index 3314a53600b..00000000000 --- a/tests/ref/test.jpeg +++ /dev/null diff --git a/tests/reftest.rs b/tests/reftest.rs deleted file mode 100644 index 376c5ac3c04..00000000000 --- a/tests/reftest.rs +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2013 The Servo Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(fs_walk)] -#![feature(slice_patterns)] -#![feature(test)] - -#[macro_use] extern crate bitflags; -extern crate image; -extern crate test; -extern crate url; -extern crate util; - -use image::{DynamicImage, GenericImage, ImageFormat, RgbImage}; -use std::env; -use std::ffi::OsStr; -use std::fs::{File, walk_dir}; -use std::io::{self, Read, Result, Write}; -use std::path::{Path, PathBuf}; -use std::process; -use std::process::{Command}; -use std::thread; -use std::time::Duration; -use test::run_tests_console; -use test::{AutoColor, DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn, ShouldPanic}; -use url::Url; - -bitflags!( - flags RenderMode: u32 { - const CPU_RENDERING = 0x00000001, - const GPU_RENDERING = 0x00000010, - const LINUX_TARGET = 0x00000100, - const MACOS_TARGET = 0x00001000, - const ANDROID_TARGET = 0x00010000 - } -); - - -fn main() { - let args: Vec<String> = env::args().collect(); - let mut parts = args[1..].split(|e| &**e == "--"); - - let harness_args = parts.next().unwrap(); // .split() is never empty - let servo_args = parts.next().unwrap_or(&[]); - - let (render_mode_string, base_path, testnames) = match harness_args { - [ref render_mode_string, ref base_path, testnames..] => - (render_mode_string, base_path, testnames), - _ => panic!("USAGE: cpu|gpu base_path [testname ...]"), - }; - - let mut render_mode = match &**render_mode_string { - "cpu" => CPU_RENDERING, - "gpu" => GPU_RENDERING, - _ => panic!("First argument must specify cpu or gpu as rendering mode") - }; - if cfg!(target_os = "linux") { - render_mode.insert(LINUX_TARGET); - } - if cfg!(target_os = "macos") { - render_mode.insert(MACOS_TARGET); - } - if cfg!(target_os = "android") { - render_mode.insert(ANDROID_TARGET); - } - - let mut all_tests = vec!(); - println!("Scanning {} for manifests\n", base_path); - - for file in walk_dir(base_path).unwrap() { - let file = file.unwrap().path(); - let maybe_extension = file.extension(); - match maybe_extension { - Some(extension) => { - if extension == OsStr::new("list") && file.is_file() { - let len = all_tests.len(); - let mut tests = parse_lists(&file, testnames, servo_args, render_mode, len); - println!("\t{} [{} tests]", file.display(), tests.len()); - all_tests.append(&mut tests); - } - } - _ => {} - } - } - - let test_opts = TestOpts { - filter: None, - run_ignored: false, - logfile: None, - run_tests: true, - bench_benchmarks: false, - nocapture: false, - color: AutoColor, - }; - - match run(test_opts, - all_tests, - servo_args.iter().cloned().collect()) { - Ok(false) => process::exit(1), // tests failed - Err(_) => process::exit(2), // I/O-related failure - _ => (), - } -} - -fn run(test_opts: TestOpts, all_tests: Vec<TestDescAndFn>, - servo_args: Vec<String>) -> io::Result<bool> { - // Verify that we're passing in valid servo arguments. Otherwise, servo - // will exit before we've run any tests, and it will appear to us as if - // all the tests are failing. - let mut command = Command::new(&servo_path()); - command - .args(&servo_args) - .arg("-z") - .arg("about:blank"); - - let mut child = match command.spawn() { - Ok(p) => p, - Err(e) => panic!("failed to execute process: {}", e), - }; - - // Wait for the shell to launch or to fail - thread::sleep(Duration::from_secs(1)); - child.kill().unwrap(); - let output = try!(child.wait_with_output()); - - let stderr = String::from_utf8(output.stderr).unwrap(); - - if stderr.contains("Unrecognized") { - println!("Servo: {}", stderr); - return Ok(false); - } - - run_tests_console(&test_opts, all_tests) -} - -#[derive(PartialEq)] -enum ReftestKind { - Same, - Different, -} - -struct Reftest { - name: String, - kind: ReftestKind, - files: [PathBuf; 2], - id: usize, - servo_args: Vec<String>, - render_mode: RenderMode, - is_flaky: bool, - prefs: Vec<String>, - fragment_identifier: Option<String>, - resolution: Option<String>, - pixel_ratio: Option<f32>, -} - -struct TestLine<'a> { - conditions: &'a str, - kind: &'a str, - file_left: &'a str, - file_right: &'a str, -} - -fn parse_lists(file: &Path, - filters: &[String], - servo_args: &[String], - render_mode: RenderMode, - id_offset: usize) - -> Vec<TestDescAndFn> { - let mut tests = Vec::new(); - let contents = { - let mut f = File::open(file).unwrap(); - let mut contents = String::new(); - f.read_to_string(&mut contents).unwrap(); - contents - }; - - for line in contents.lines() { - // ignore comments or empty lines - if line.starts_with("#") || line.is_empty() { - continue; - } - - let parts: Vec<&str> = line.split(' ').filter(|p| !p.is_empty()).collect(); - - let test_line = match parts.len() { - 3 => TestLine { - conditions: "", - kind: parts[0], - file_left: parts[1], - file_right: parts[2], - }, - 4 => TestLine { - conditions: parts[0], - kind: parts[1], - file_left: parts[2], - file_right: parts[3], - }, - _ => panic!("reftest line: '{}' doesn't match '[CONDITIONS] KIND LEFT RIGHT'", line), - }; - - let kind = match test_line.kind { - "==" => ReftestKind::Same, - "!=" => ReftestKind::Different, - part => panic!("reftest line: '{}' has invalid kind '{}'", line, part) - }; - - let base = env::current_dir().unwrap().join(file.parent().unwrap()); - - let file_left = base.join(test_line.file_left); - let file_right = base.join(test_line.file_right); - - let conditions_list = test_line.conditions.split(','); - let mut flakiness = RenderMode::empty(); - let mut prefs = vec![]; - let mut fragment_identifier = None; - let mut resolution = None; - let mut pixel_ratio = None; - for condition in conditions_list { - match condition { - "flaky_cpu" => flakiness.insert(CPU_RENDERING), - "flaky_gpu" => flakiness.insert(GPU_RENDERING), - "flaky_linux" => flakiness.insert(LINUX_TARGET), - "flaky_macos" => flakiness.insert(MACOS_TARGET), - _ => () - } - if condition.starts_with("prefs:\"") { - if let Some(joined) = condition.split("\"").nth(1) { - prefs.extend(joined.split(",").map(str::to_owned)); - } - } - if condition.starts_with("fragment=") { - fragment_identifier = Some(condition["fragment=".len()..].to_string()); - } - if condition.starts_with("resolution=") { - resolution = Some(condition["resolution=".len() ..].to_string()); - } - if condition.starts_with("device-pixel-ratio=") { - pixel_ratio = Some(condition["device-pixel-ratio=".len() ..].to_string() - .parse().expect("Invalid device-pixel-ratio")); - } - } - - let reftest = Reftest { - name: format!("{} {} {}", test_line.file_left, test_line.kind, test_line.file_right), - kind: kind, - files: [file_left, file_right], - id: id_offset + tests.len(), - render_mode: render_mode, - servo_args: servo_args.to_vec(), - is_flaky: render_mode.intersects(flakiness), - prefs: prefs, - fragment_identifier: fragment_identifier, - resolution: resolution, - pixel_ratio: pixel_ratio, - }; - - if filters.is_empty() || filters.iter().any(|pattern| reftest.name.contains(pattern)) { - tests.push(make_test(reftest)); - } - } - tests -} - -fn make_test(reftest: Reftest) -> TestDescAndFn { - let name = reftest.name.clone(); - TestDescAndFn { - desc: TestDesc { - name: DynTestName(name), - ignore: false, - should_panic: ShouldPanic::No, - }, - testfn: DynTestFn(Box::new(move || { - check_reftest(reftest); - })), - } -} - -fn capture(reftest: &Reftest, side: usize) -> (u32, u32, Vec<u8>) { - let png_filename = format!("/tmp/servo-reftest-{:06}-{}.png", reftest.id, side); - let mut command = Command::new(&servo_path()); - command - .args(&reftest.servo_args[..]) - .arg("--user-stylesheet").arg(util::resource_files::resources_dir_path().join("ahem.css")) - // Allows pixel perfect rendering of Ahem font and the HTML canvas for reftests. - .arg("-Z") - .arg("disable-text-aa,disable-canvas-aa") - .args(&["-f", "-o"]) - .arg(&png_filename) - .arg(&{ - let mut url = Url::from_file_path(&*reftest.files[side]).unwrap(); - url.fragment = reftest.fragment_identifier.clone(); - url.to_string() - }); - // CPU rendering is the default - if reftest.render_mode.contains(CPU_RENDERING) { - command.arg("-c"); - } - if reftest.render_mode.contains(GPU_RENDERING) { - command.arg("-g"); - } - for pref in &reftest.prefs { - command.arg("--pref"); - command.arg(pref); - } - if let Some(ref resolution) = reftest.resolution { - command.arg("--resolution"); - command.arg(resolution); - } - if let Some(pixel_ratio) = reftest.pixel_ratio { - command.arg("--device-pixel-ratio"); - command.arg(pixel_ratio.to_string()); - } - let (exit_status, stderr, stdout) = match command.output() { - Ok(output) => (output.status, output.stderr, output.stdout), - Err(e) => panic!("failed to execute process: {}", e), - }; - - if !stdout.is_empty() { - let stdout_filename = format!("/tmp/servo-reftest-{:06}-{}-stdout.txt", reftest.id, side); - let mut stdout_file = File::create(stdout_filename).unwrap(); - stdout_file.write_all(&stdout[..]).unwrap(); - } - - if !stderr.is_empty() { - let stderr_filename = format!("/tmp/servo-reftest-{:06}-{}-stderr.txt", reftest.id, side); - let mut stderr_file = File::create(stderr_filename).unwrap(); - stderr_file.write_all(&stderr[..]).unwrap(); - } - - assert!(exit_status.success()); - - let image = match image::open(&png_filename) { - Ok(DynamicImage::ImageRgb8(image)) => image, - Ok(image) => image.to_rgb(), - _ => panic!(), - }; - (image.width(), image.height(), image.into_raw()) -} - -fn servo_path() -> PathBuf { - let current_exe = env::current_exe().ok().expect("Could not locate current executable"); - current_exe.parent().unwrap().join("servo") -} - -fn check_reftest(reftest: Reftest) { - let (left_width, left_height, left_bytes) = capture(&reftest, 0); - let (right_width, right_height, right_bytes) = capture(&reftest, 1); - - // TODO(gw): This is a workaround for https://github.com/servo/servo/issues/7730 - if !reftest.is_flaky { - assert_eq!(left_width, right_width); - assert_eq!(left_height, right_height); - - let left_all_white = left_bytes.iter().all(|&p| p == 255); - let right_all_white = right_bytes.iter().all(|&p| p == 255); - - if left_all_white && right_all_white { - panic!("Both renderings are empty") - } - } - - let pixels = left_bytes.iter().zip(right_bytes.iter()).map(|(&a, &b)| { - if a == b { - // White for correct - 0xFF - } else { - // "1100" in the RGBA channel with an error for an incorrect value - // This results in some number of C0 and FFs, which is much more - // readable (and distinguishable) than the previous difference-wise - // scaling but does not require reconstructing the actual RGBA pixel. - 0xC0 - } - }).collect::<Vec<u8>>(); - - if pixels.iter().any(|&a| a < 255) { - let output = format!("/tmp/servo-reftest-{:06}-diff.png", reftest.id); - let mut file = File::create(&output).unwrap(); - let img_buf = RgbImage::from_raw(left_width, left_height, pixels).expect("foo"); - DynamicImage::ImageRgb8(img_buf).save(&mut file, ImageFormat::PNG).unwrap(); - - match (reftest.kind, reftest.is_flaky) { - (ReftestKind::Same, true) => println!("flaky test - rendering difference: {}", output), - (ReftestKind::Same, false) => panic!("rendering difference: {}", output), - (ReftestKind::Different, _) => {} // Result was different and that's what was expected - } - } else { - assert!(reftest.is_flaky || reftest.kind == ReftestKind::Same); - } -} diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index d6fc30b6a8f..44620f9b226 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -151,6 +151,19 @@ "url": "/_mozilla/css/acid1_a.html" } ], + "css/acid2-wrapper.html": [ + { + "path": "css/acid2-wrapper.html", + "references": [ + [ + "/_mozilla/css/acid2_ref_broken.html", + "==" + ] + ], + "timeout": "long", + "url": "/_mozilla/css/acid2-wrapper.html" + } + ], "css/acid2_noscroll.html": [ { "path": "css/acid2_noscroll.html", @@ -163,6 +176,18 @@ "url": "/_mozilla/css/acid2_noscroll.html" } ], + "css/acid2_ref.html": [ + { + "path": "css/acid2_ref.html", + "references": [ + [ + "/_mozilla/css/acid2_ref_broken.html", + "==" + ] + ], + "url": "/_mozilla/css/acid2_ref.html" + } + ], "css/after_block_iteration.html": [ { "path": "css/after_block_iteration.html", @@ -6194,6 +6219,19 @@ "url": "/_mozilla/css/acid1_a.html" } ], + "css/acid2-wrapper.html": [ + { + "path": "css/acid2-wrapper.html", + "references": [ + [ + "/_mozilla/css/acid2_ref_broken.html", + "==" + ] + ], + "timeout": "long", + "url": "/_mozilla/css/acid2-wrapper.html" + } + ], "css/acid2_noscroll.html": [ { "path": "css/acid2_noscroll.html", @@ -6206,6 +6244,18 @@ "url": "/_mozilla/css/acid2_noscroll.html" } ], + "css/acid2_ref.html": [ + { + "path": "css/acid2_ref.html", + "references": [ + [ + "/_mozilla/css/acid2_ref_broken.html", + "==" + ] + ], + "url": "/_mozilla/css/acid2_ref.html" + } + ], "css/after_block_iteration.html": [ { "path": "css/after_block_iteration.html", diff --git a/tests/wpt/mozilla/meta/css/acid2-wrapper.html.ini b/tests/wpt/mozilla/meta/css/acid2-wrapper.html.ini new file mode 100644 index 00000000000..f2657877a44 --- /dev/null +++ b/tests/wpt/mozilla/meta/css/acid2-wrapper.html.ini @@ -0,0 +1,3 @@ +[acid2-wrapper.html] + type: reftest + disabled: https://github.com/servo/servo/issues/9310 diff --git a/tests/wpt/mozilla/meta/css/acid2_ref.html.ini b/tests/wpt/mozilla/meta/css/acid2_ref.html.ini new file mode 100644 index 00000000000..55dd5ca27f3 --- /dev/null +++ b/tests/wpt/mozilla/meta/css/acid2_ref.html.ini @@ -0,0 +1,3 @@ +[acid2_ref.html] + type: reftest + expected: FAIL diff --git a/tests/wpt/mozilla/tests/css/acid2-wrapper.html b/tests/wpt/mozilla/tests/css/acid2-wrapper.html new file mode 100644 index 00000000000..d1907a92b64 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/acid2-wrapper.html @@ -0,0 +1,15 @@ +<!doctype html> +<html class=reftest-wait> +<meta name=timeout content=long> +<link rel=match href=acid2_ref_broken.html> +<style> +body { + margin: 0; +} +iframe { + width: 100vw; + height: 100vh; + border: 0; +} +</style> +<iframe src="acid2.html#top" onload="document.documentElement.className = ''"></iframe> diff --git a/tests/wpt/mozilla/tests/css/acid2.html b/tests/wpt/mozilla/tests/css/acid2.html new file mode 100755 index 00000000000..2f700b14e71 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/acid2.html @@ -0,0 +1,150 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html> + <head> + <title>The Second Acid Test</title> + <style type="text/css"> + /* section numbers refer to CSS2.1 */ + + /* page setup */ + html { font: 12px sans-serif; margin: 0; padding: 0; overflow: hidden; /* hides scrollbars on viewport, see 11.1.1:3 */ background: white; color: red; } + body { margin: 0; padding: 0; } + + /* introduction message */ + .intro { font: 2em sans-serif; margin: 3.5em 2em; padding: 0.5em; border: solid thin; background: white; color: black; position: relative; z-index: 2; /* should cover the black and red bars that are fixed-positioned */ } + .intro * { font: inherit; margin: 0; padding: 0; } + .intro h1 { font-size: 1em; font-weight: bolder; margin: 0; padding: 0; } + .intro :link { color: blue; } + .intro :visited { color: purple; } + + /* picture setup */ + #top { margin: 100em 3em 0; padding: 2em 0 0 .5em; text-align: left; font: 2em/24px sans-serif; color: navy; white-space: pre; } /* "Hello World!" text */ + .picture { position: relative; border: 1em solid transparent; margin: 0 0 100em 3em; } /* containing block for face */ + .picture { background: red; } /* overridden by preferred stylesheet below */ + + /* top line of face (scalp): fixed positioning and min/max height/width */ + .picture p { position: fixed; margin: 0; padding: 0; border: 0; top: 9em; left: 11em; width: 140%; max-width: 4em; height: 8px; min-height: 1em; max-height: 2mm; /* min-height overrides max-height, see 10.7 */ background: black; border-bottom: 0.5em yellow solid; } + + /* bits that shouldn't be part of the top line (and shouldn't be visible at all): HTML parsing, "+" combinator, stacking order */ + .picture p.bad { border-bottom: red solid; /* shouldn't matter, because the "p + table + p" rule below should match it too, thus hiding it */ } + .picture p + p { background: maroon; z-index: 1; } /* shouldn't match anything */ + .picture p + table + p { margin-top: 3em; /* should end up under the absolutely positioned table below, and thus not be visible */ } + + /* second line of face: attribute selectors, float positioning */ + [class~=one].first.one { position: absolute; top: 0; margin: 36px 0 0 60px; padding: 0; border: black 2em; border-style: none solid; /* shrink wraps around float */ } + [class~=one][class~=first] [class=second\ two][class="second two"] { float: right; width: 48px; height: 12px; background: yellow; margin: 0; padding: 0; } /* only content of abs pos block */ + + /* third line of face: width and overflow */ + .forehead { margin: 4em; width: 8em; border-left: solid black 1em; border-right: solid black 1em; background: red url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4%2F58BAAT%2FAf9jgNErAAAAAElFTkSuQmCC); /* that's a 1x1 yellow pixel PNG */ } + .forehead * { width: 12em; line-height: 1em; } + + /* class selectors headache */ + .two.error.two { background: maroon; } /* shouldn't match */ + .forehead.error.forehead { background: red; } /* shouldn't match */ + [class=second two] { background: red; } /* this should be ignored (invalid selector -- grammar says it only accepts IDENTs or STRINGs) */ + + /* fourth and fifth lines of face, with eyes: paint order test (see appendix E) and fixed backgrounds */ + /* the two images are identical: 2-by-2 squares with the top left + and bottom right pixels set to yellow and the other two set to + transparent. Since they are offset by one pixel from each other, + the second one paints exactly over the transparent parts of the + first one, thus creating a solid yellow block. */ + .eyes { position: absolute; top: 5em; left: 3em; margin: 0; padding: 0; background: red; } + #eyes-a { height: 0; line-height: 2em; text-align: right; } /* contents should paint top-most because they're inline */ + #eyes-a object { display: inline; vertical-align: bottom; } + #eyes-a object[type] { width: 7.5em; height: 2.5em; } /* should have no effect since that object should fallback to being inline (height/width don't apply to inlines) */ + #eyes-a object object object { border-right: solid 1em black; padding: 0 12px 0 11px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D) fixed 1px 0; } + #eyes-b { float: left; width: 10em; height: 2em; background: fixed url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D); border-left: solid 1em black; border-right: solid 1em red; } /* should paint in the middle layer because it is a float */ + #eyes-c { display: block; background: red; border-left: 2em solid yellow; width: 10em; height: 2em; } /* should paint bottom most because it is a block */ + + /* lines six to nine, with nose: auto margins */ + .nose { float: left; margin: -2em 2em -1em; border: solid 1em black; border-top: 0; min-height: 80%; height: 60%; max-height: 3em; /* percentages become auto (see 10.5 and 10.7) and intrinsic height is more than 3em, so 3em wins */ padding: 0; width: 12em; } + .nose > div { padding: 1em 1em 3em; height: 0; background: yellow; } + .nose div div { width: 2em; height: 2em; background: red; margin: auto; } + .nose :hover div { border-color: blue; } + .nose div:hover :before { border-bottom-color: inherit; } + .nose div:hover :after { border-top-color: inherit; } + .nose div div:before { display: block; border-style: none solid solid; border-color: red yellow black yellow; border-width: 1em; content: ''; height: 0; } + .nose div :after { display: block; border-style: solid solid none; border-color: black yellow red yellow; border-width: 1em; content: ''; height: 0; } + + /* between lines nine and ten: margin collapsing with 'float' and 'clear' */ + .empty { margin: 6.25em; height: 10%; /* computes to auto which makes it empty per 8.3.1:7 (own margins) */ } + .empty div { margin: 0 2em -6em 4em; } + .smile { margin: 5em 3em; clear: both; /* clearance is negative (see 8.3.1 and 9.5.1) */ } + + /* line ten and eleven: containing block for abs pos */ + .smile div { margin-top: 0.25em; background: black; width: 12em; height: 2em; position: relative; bottom: -1em; } + .smile div div { position: absolute; top: 0; right: 1em; width: auto; height: 0; margin: 0; border: yellow solid 1em; } + + /* smile (over lines ten and eleven): backgrounds behind borders, inheritance of 'float', nested floats, negative heights */ + .smile div div span { display: inline; margin: -1em 0 0 0; border: solid 1em transparent; border-style: none solid; float: right; background: black; height: 1em; } + .smile div div span em { float: inherit; border-top: solid yellow 1em; border-bottom: solid black 1em; } /* zero-height block; width comes from (zero-height) child. */ + .smile div div span em strong { width: 6em; display: block; margin-bottom: -1em; /* should have no effect, since parent has top&bottom borders, so this margin doesn't collapse */ } + + /* line twelve: line-height */ + .chin { margin: -4em 4em 0; width: 8em; line-height: 1em; border-left: solid 1em black; border-right: solid 1em black; background: yellow url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAAAAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D) /* 64x64 red square */ no-repeat fixed /* shouldn't be visible unless the smiley is moved to the top left of the viewport */; } + .chin div { display: inline; font: 2px/4px serif; } + + /* line thirteen: cascade and selector tests */ + .parser-container div { color: maroon; border: solid; color: orange; } /* setup */ + div.parser-container * { border-color: black; /* overrides (implied) border-color on previous line */ } /* setup */ + * div.parser { border-width: 0 2em; /* overrides (implied) declarations on earlier line */ } /* setup */ + + /* line thirteen continued: parser tests */ + .parser { /* comment parsing test -- comment ends before the end of this line, the backslash should have no effect: \*/ } + .parser { margin: 0 5em 1em; padding: 0 1em; width: 2em; height: 1em; error: \}; background: yellow; } /* setup with parsing test */ + * html .parser { background: gray; } + \.parser { padding: 2em; } + .parser { m\argin: 2em; }; + .parser { height: 3em; } + .parser { width: 200; } + .parser { border: 5em solid red ! error; } + .parser { background: red pink; } + + /* line fourteen (last line of face): table */ + ul { display: table; padding: 0; margin: -1em 7em 0; background: red; } + ul li { padding: 0; margin: 0; } + ul li.first-part { display: table-cell; height: 1em; width: 1em; background: black; } + ul li.second-part { display: table; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */ + ul li.third-part { display: table-cell; height: 0.5em; /* gets stretched to fit row */ width: 1em; background: black; } + ul li.fourth-part { list-style: none; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */ + + /* bits that shouldn't appear: inline alignment in cells */ + .image-height-test { height: 10px; overflow: hidden; font: 20em serif; } /* only the area between the top of the line box and the top of the image should be visible */ + table { margin: 0; border-spacing: 0; } + td { padding: 0; } + + </style> + <link rel="appendix stylesheet" href="data:text/css,.picture%20%7B%20background%3A%20none%3B%20%7D"> <!-- this stylesheet should be applied by default --> + </head> + <body> + <div class="intro"> + <h1>Standards compliant?</h1> + <p><a href="#top">Take The Acid2 Test</a> and compare it to <a + href="reference.html">the reference rendering</a>.</p> + </div> + <h2 id="top">Hello World!</h2> + <div class="picture"> + <p><table><tr><td></table><p class="bad"> <!-- <table> closes <p> per the HTML4 DTD --> + <blockquote class="first one"><address class="second two"></address></blockquote> + <div class="forehead"><div> </div></div> + <div class="eyes"><div id="eyes-a"><object data="data:application/x-unknown,ERROR"><object data="http://www.damowmow.com/404/" type="text/html"><object data="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAFy7sgCAAAGsUlEQVRo3u2ZbWwcZxHHf3s%2B7LNbO3ZjXBtowprGODRX0qpNQCjmJKuVKhMl1P2AkCwhFOIKkCBSm9IXavGFKAixIAECwkmWo5MrhRI3Ub40IEwQgp6aIDg3Cd6eEqyIHEteah%2B1E69vhw%2BZtTaX8704ZzkKjHS6271nZ56ZZ%2BY%2F%2F%2BdZKF%2FCwYshx3EkkggLsD1v4FQkEZZYLCbAKyG9%2Ba9EIsG6hnUAf8x74K3aUC3j4%2BM54HcsR2oAIomwZOezkv%2FnSHpYNh%2BNCmAE7xv94zvFdd1bHsjMZmQkPSxAJP%2B%2FfuBLwK54PC7JZFKAVJmzXLBt2w%2FMvcDLwIb8QS8CeJ4nkURYIomw7J%2FYJ8BvSiiXptGGxWds2%2Fa9%2Bnaxh%2BYAD%2Bgt04NDgABTpQY2cvvSFLzw86gWeBVwC8SzlOSv2YeBPfmDBoBHgKmR9LBEEmHZfDTqGykqfkUE0nA78BzQGfSgUeP3wNeTXwXg7MwZDhw4UHL6ra2ti79%2FOvljgG8AZ4H64Lhm4MvAocxsRppGG%2FxcXihlwLIs6R%2FfKV2HO%2F26uA94pdDYUKUZUU7W1RQYXA98Gnhaf5%2FXWX0HeAHYoQonqa4sZSOsSWMCWeC9Yko%2BCQwBe4E6oNc0Tc91XTl1%2BaTsn9gnI%2Blhyc5nZWxsrBIkKSbl2tiic3tW53YDEwOKaoFBrcOfqKee53lG9xsPMjV784r%2F4lO%2FpPvyJ9iyZcuvFSaXK5XYeAZ4CDgGvB3MS4B54LQuWYPeuy4iRFsevsXqpuYoqVQKIH2bK1CuDQNo11o4XUzh%2FcDWYIe1LEtyuZx4niee54njOGKapgfsqlL%2Bl2OjEXg8nxrc1dJ0h3hbtL%2BGCtz7KPBF4CuBe9uB15VafE8hr9qylI3HgG8C2%2FK7VyHZoJj7MrBRm30qFotJMpkU27YlHo%2F7Ha5a%2BV%2FKRkSJ4KuKRLVLKapTjB1SzAVIjY2NSXY%2BKyPpYdk%2FsU9OXT4pruv6BdZbBQfKsVGnvWlIe1VB6VQO8JxC1vZYLCbZ%2BaxsPhpdZDyRRFhG0sPiOE6ldKBg2lRg4xF1YCDIIIKN7DGgD3gH%2BBXwejKZfPrs2tPs%2FvPN2bKuYR1nd7xLKBSSJeqoXKnERjPwNWAG%2BLn2rZuM%2B4Tpml6vaWlp4eLcxVusZq5lCgVgOVKJjRqdX86ffL4D5wIoZACnTpw4wRMdT96i%2FImOJxERAs4uVyqxUacF%2FPdiCj%2BjdRBRGFtwXVdG0sPSdbhTmkYbpH98p2RmM2JZlig1vl0GWo4NQ%2Fn%2Bs5pKRXfwjweaxy7TND3HcRZbfC6X8xVPVQlGy7WxVWlO5XRXFXm6EZmrQuSXYyPE3SiVoEhE6Wyr0u2rumO6zv%2B21AFdQAswC1wCMuUCXCmyWQus103Qg8qlDO0lxwOb%2Fl4FiK3AB3VS%2FuKKLtK%2FgbeAnwG%2FvUODuRw%2FFrR0H1UC75fwu8oJ%2FhFsW5VIG%2FBUgEIN6Y65O4AHu4Ap0zQ9y7LEcZyb9lRBUHQcRyzL8unZVBW5bFWAvAp%2BhDQ2g4F47dUYtlU6obXA54DnVdFLekjUGGifh4AFy7LEdV3xj3X9I66m0QZpGm2QrsOd0j%2B%2BU0bSw5KZzYjrun6HWlAd961i4FfCj0aN1Usau%2Bc1lmuXPFwvAEumUut7tQQvAb%2FXb%2FT0bCAej9cODg7yt%2Bm%2F8q2%2F7OUHZ76PnZ1k2p0mJzlykmPancbOTnL0whHs7CQfb%2B5mx2d3sH79%2BtCRI0c6FeaOr9ICrIQfLvA%2B8BGNXxi4R6HrisJVUWrxAVW2oMFf0Aczim8o3kV6enowDIPjF9%2Fk%2BMU3S3rrjzMMg56eHr%2BxP7qKFbASfojG6kpeDGs1tiW53RxwWT%2Bin5q8w4xpQK5evQpAR30H7ZH2khNvj7TTUd8BgD4rqmu1ZKX8qNeY%2BfHz4zlXDgT5E8tpCTUq7XSBC4Euv8227TV9fX1E73%2BYtvo27BmbS9cvFVTY3bSRFza9yOcf6Gfmygy7d%2B%2Fm%2FPnzF4DvrsBLhnJlJfwIKXxv1PheAE4qK6p4H9AGbNKTuhngBPBPXYRe4IemaT5kWZbR19fHNbmGnZ1k4r3U4glDR30Hm5qjbGjsImJEOHbsGHv27JFz5869o0eFq01Jq%2BmHAXwI6FFKagMTgHM7GzFDS%2BoeLSMv7zjzC9x4Y7gxFovVDAwMEI1GaWlpWSzRVCrFwYMH%2FXfxZ4AfAa8B%2F7lDaGg1%2FQgp43lfK0yqtRMuJa3ceKe5DfgYsCYAZ2ngD8CfAkzqTpW7xY%2F%2FSznyX%2FVeUb2kVmX4AAAAAElFTkSuQmCC">ERROR</object></object></object></div><div id="eyes-b"></div><div id="eyes-c"></div></div> <!-- that's a PNG with 8bit alpha containing two eyes --> + <div class="nose"><div><div></div></div></div> + <div class="empty"><div></div></div> + <div class="smile"><div><div><span><em><strong></strong></em></span></div></div></div> + <div class="chin"><div> </div></div> + <div class="parser-container"><div class="parser"><!-- ->ERROR<!- --></div></div> <!-- two dashes is what delimits a comment, so the text "->ERROR<!-" earlier on this line is actually part of a comment --> + <ul> + <li class="first-part"></li> + <li class="second-part"></li> + <li class="third-part"></li> + <li class="fourth-part"></li> + </ul> + <div class="image-height-test"><table><tr><td><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAAAAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D" alt=""></td></tr></table></div> + </div> + <script> +// window.scroll(0, 2684); +// setInterval(() => { console.log(window.scrollY); window.scroll(0, 2684); +//}, 10); + </script> + </body> +</html> diff --git a/tests/ref/acid2_ref.html b/tests/wpt/mozilla/tests/css/acid2_ref.html index a6cc0c01b28..d0b4e28ec3e 100644 --- a/tests/ref/acid2_ref.html +++ b/tests/wpt/mozilla/tests/css/acid2_ref.html @@ -2,6 +2,7 @@ <html> <head> <title>The Second Acid Test (Reference Rendering)</title> + <link rel=match href=acid2_ref_broken.html> <style type="text/css"> html { margin: 0; padding: 0; border: 0; overflow: hidden; background: white; } body { margin: 0; padding: 0; border: 0; } diff --git a/tests/ref/acid2_ref.png b/tests/wpt/mozilla/tests/css/acid2_ref.png Binary files differindex 7aee7609d6a..7aee7609d6a 100644 --- a/tests/ref/acid2_ref.png +++ b/tests/wpt/mozilla/tests/css/acid2_ref.png |