TestInvocationQt.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (C) 2011 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "TestInvocation.h"
  27. #include "PlatformWebView.h"
  28. #include "TestController.h"
  29. #include <QBuffer>
  30. #include <QCryptographicHash>
  31. #include <QtGui/QPainter>
  32. #include <WebKit2/WKImageQt.h>
  33. #include <stdio.h>
  34. #include <wtf/Assertions.h>
  35. namespace WTR {
  36. static void dumpImage(const QImage& image)
  37. {
  38. QBuffer buffer;
  39. buffer.open(QBuffer::WriteOnly);
  40. image.save(&buffer, "PNG");
  41. buffer.close();
  42. const QByteArray& data = buffer.data();
  43. printf("Content-Type: %s\n", "image/png");
  44. printf("Content-Length: %lu\n", static_cast<unsigned long>(data.length()));
  45. const quint32 bytesToWriteInOneChunk = 1 << 15;
  46. quint32 dataRemainingToWrite = data.length();
  47. const char* ptr = data.data();
  48. while (dataRemainingToWrite) {
  49. quint32 bytesToWriteInThisChunk = qMin(dataRemainingToWrite, bytesToWriteInOneChunk);
  50. quint32 bytesWritten = fwrite(ptr, 1, bytesToWriteInThisChunk, stdout);
  51. if (bytesWritten != bytesToWriteInThisChunk)
  52. break;
  53. dataRemainingToWrite -= bytesWritten;
  54. ptr += bytesWritten;
  55. }
  56. fflush(stdout);
  57. }
  58. void TestInvocation::forceRepaintDoneCallback(WKErrorRef, void *context)
  59. {
  60. static_cast<TestInvocation*>(context)->m_gotRepaint = true;
  61. TestController::shared().notifyDone();
  62. }
  63. void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef imageRef, WKArrayRef repaintRects)
  64. {
  65. QImage image;
  66. if (PlatformWebView::windowShapshotEnabled()) {
  67. WKPageRef page = TestController::shared().mainWebView()->page();
  68. WKPageForceRepaint(page, this, &forceRepaintDoneCallback);
  69. TestController::shared().runUntil(m_gotRepaint, TestController::ShortTimeout);
  70. if (m_gotRepaint)
  71. image = WKImageCreateQImage(TestController::shared().mainWebView()->windowSnapshotImage().get());
  72. else {
  73. m_error = true;
  74. m_errorMessage = "Timed out waiting for repaint\n";
  75. m_webProcessIsUnresponsive = true;
  76. return;
  77. }
  78. } else
  79. image = WKImageCreateQImage(imageRef);
  80. if (repaintRects) {
  81. QImage mask(image.size(), image.format());
  82. mask.fill(QColor(0, 0, 0, 0.66 * 255));
  83. QPainter maskPainter(&mask);
  84. maskPainter.setCompositionMode(QPainter::CompositionMode_Source);
  85. size_t count = WKArrayGetSize(repaintRects);
  86. for (size_t i = 0; i < count; ++i) {
  87. WKRect wkRect = WKRectGetValue(static_cast<WKRectRef>(WKArrayGetItemAtIndex(repaintRects, i)));
  88. QRectF rect(wkRect.origin.x, wkRect.origin.y, wkRect.size.width, wkRect.size.height);
  89. maskPainter.fillRect(rect, Qt::transparent);
  90. }
  91. QPainter painter(&image);
  92. painter.drawImage(image.rect(), mask);
  93. }
  94. QCryptographicHash hash(QCryptographicHash::Md5);
  95. for (unsigned row = 0; row < image.height(); ++row)
  96. hash.addData(reinterpret_cast<const char*>(image.constScanLine(row)), image.bytesPerLine());
  97. QByteArray actualHash = hash.result().toHex();
  98. ASSERT(actualHash.size() == 32);
  99. if (!compareActualHashToExpectedAndDumpResults(actualHash)) {
  100. image.setText("checksum", actualHash);
  101. dumpImage(image);
  102. }
  103. }
  104. } // namespace WTR